我有一个WinRT / C#/ XAML应用程序,其视图具有垂直ListView项目。根据项目的数量,ListView显示垂直滚动条。这是XAML的定义:
<UserControl.Resources>
<CollectionViewSource
x:Name="myViewSource"
Source="{Binding myViewModel.Items}" />
</UserControl.Resources>
...
<ListView
x:Name="myListView"
ItemsSource="{Binding Source={StaticResource myViewSource}}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
</ListView>
现在,每当我导航到此视图时,ListView的所选项目都是通过从后面的代码(OnNavigatedTo
)设置视图模型中的数据绑定SelectedItem属性来选择的。我的问题:ListView不会自动滚动到此选定项目。滚动条保留在ListView的顶部,用户必须手动滚动才能看到所选项目。
我在后面的代码(在myListView.ScrollIntoView(MyViewModel.SelectedItem);
)中设置SelectedItem之后尝试执行OnNavigatedTo
,但它不起作用。滚动条保持在顶部。
我在SO上知道这个帖子:Scroll WinRT ListView to particular group。 这似乎是一个类似的问题。但是当我手动或使用WinRT XAML Toolkit遍历ListView的可视树时,它找不到ScrollViewer(而是返回null)。
答案 0 :(得分:15)
感谢Filip,我注意到在ScrollIntoView()
中调用OnNavigatedTo()
为时尚早,因为ListView
控件尚未在此处加载。
第一个解决方案是绑定ListView的Loaded
事件:
myListView.Loaded += (s, e) =>
myListView.ScrollIntoView(MyViewModel.SelectedItem);
不幸的是,这导致了令人讨厌的视觉效果,在所有内容重新排列好之前,当前ListView项目与所选项目重叠一段时间。“/ p>
我找到的最终解决方案是通过视图的ScrollIntoView()
异步调用Dispatcher
:
myListView.Loaded += (s, e) => Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() => myListView.ScrollIntoView(MyViewModel.SelectedItem));
使用此解决方案,布局工作正常。
答案 1 :(得分:1)
我有类似的需求并以稍微不同的方式解决它。我从ListView订阅了SelectionChangedEvent并在处理程序中执行了滚动。
XAML:
<ListView x:Name="myListView" SelectionChanged="myListView_SelectionChanged" ...>
</ListView>
代码:
private void myListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
myListView.ScrollIntoView(myListView.SelectedItem);
}