让ListView滚动到所选项目

时间:2012-08-24 11:23:15

标签: xaml windows-runtime winrt-xaml

我有一个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)。

2 个答案:

答案 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);
}