滚动ListViewItem位于ListView的顶部
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滚动ListViewItem位于ListView的顶部相关的知识,希望对你有一定的参考价值。
在WPF中,我知道我可以使用ListView.ScrollIntoView
将特定项目滚动到视图中,但它总是会进行最少量的滚动以便显示项目。
如何使其滚动以便我想要显示的项目滚动到ListView的顶部?
我曾经考虑过两次调用ScrollIntoView,一次是针对我想要的项目,一次针对最后显示的项目,但我不知道如何找出最后显示的项目。
我们可以通过获取ListView的ControlTemplate中存在的ScrollViewer来实现。如果您可以访问ScrollViewer,则会显示不同滚动方法的a lot。
首先,我们可以创建一个我们想要将此效果添加到的ListView:
<ListView ItemsSource="{Binding Percents}"
SelectionChanged="OnSelectionChanged"
x:Name="uiListView"/>
public List<int> Percents { get; set; }
public Window1()
{
InitializeComponent();
Percents = new List<int>();
for (int i = 1; i <= 100; i++)
{
Percents.Add(i);
}
this.DataContext = this;
}
我们还需要一些可以从ListView获取ScrollViewer的东西。我以前使用类似于此的东西来处理自定义滚动,我们也可以在这里使用它。
public static DependencyObject GetScrollViewer(DependencyObject o)
{
if (o is ScrollViewer)
{ return o; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
现在,我们只需要处理SelectionChanged事件。因为我们正在尝试将项目滚动到列表的顶部,所以最好的选项是滚动到底部,然后重新向上滚动到我们选择的项目。正如您所说,ScrollIntoView将滚动直到项目可见,因此一旦所选项目向上滚动回到顶部,它将停止我们所选项目在列表的最顶部。
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer;
scrollViewer.ScrollToBottom();
uiListView.ScrollIntoView(e.AddedItems[0]);
}
这是@rmoore的答案的替代方案,可以避免滚动到底部。另请注意,这仅适用于SelectionMode=Single
的情况。
如果ScrollViewer.CanContentScroll=True
ScrollViewer
可以直接滚动到SelectedIndex
。
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer;
scrollViewer.ScrollToVerticalOffset(listView.SelectedIndex);
}
如果ScrollViewer.CanContentScroll=False
需要一些额外的XAML:
<ListView ScrollViewer.CanContentScroll="False" ItemsSource="{Binding Percents}" x:Name="uiListView">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="Selected" Handler="OnSelected"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
并且ScrollViewer
可以移动到ListViewItem
顶部的垂直偏移。
private void OnSelected(object sender, RoutedEventArgs e)
{
ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer;
ListViewItem listViewItem = (ListViewItem)e.Source;
Point offset = listViewItem.TranslatePoint(new Point(), scrollViewer);
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset.Y);
}
以上是关于滚动ListViewItem位于ListView的顶部的主要内容,如果未能解决你的问题,请参考以下文章
ListView 中的点指示器 Flutter 中的水平滚动
更新单个 ListViewItem 的文本时如何防止 ListView 闪烁?
从 ListView 获取 ListViewItem 而不是 Item