让ListView滚动到所选项目

Mat*_*ias 4 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>
Run Code Online (Sandbox Code Playgroud)

现在,每当我导航到此视图时,通过在代码隐藏(OnNavigatedTo)中设置视图模型中的数据绑定SelectedItem属性来选择ListView的所选项.我的问题:ListView不会自动滚动到此选定项目.滚动条保留在ListView的顶部,用户必须手动滚动才能看到所选项目.

我尝试myListView.ScrollIntoView(MyViewModel.SelectedItem);在后面(in OnNavigatedTo)中的代码中设置SelectedItem后执行,但它不起作用.滚动条保持在顶部.

我在SO上知道这个帖子:将WinRT ListView滚动到特定组.这似乎是一个类似的问题.但是当我手动或使用WinRT XAML Toolkit遍历ListView的可视树时,它找不到ScrollViewer(而是返回null).

Mat*_*ias 15

感谢菲利普我注意到,呼吁ScrollIntoView()OnNavigatedTo()为时太早,因为ListView控制不是在这个地方没有加载.

第一个解决方案的想法是绑定LoadedListView 的事件:

myListView.Loaded += (s, e) => 
    myListView.ScrollIntoView(MyViewModel.SelectedItem);
Run Code Online (Sandbox Code Playgroud)

不幸的是,在所有内容重新排列良好之前,会导致令人讨厌的视觉效果,其中当前ListView项目与所选项目重叠一段时间.

我找到的最终解决方案是ScrollIntoView()通过Dispatcher视图异步调用:

myListView.Loaded += (s, e) => Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    () => myListView.ScrollIntoView(MyViewModel.SelectedItem));
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,布局工作正常.


den*_*ver 5

我有类似的需求并以略有不同的方式解决它。我从 ListView 订阅了 SelectionChangedEvent 并在处理程序中执行了滚动。

XAML:

<ListView x:Name="myListView" SelectionChanged="myListView_SelectionChanged" ...>
</ListView>
Run Code Online (Sandbox Code Playgroud)

代码:

private void myListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    myListView.ScrollIntoView(myListView.SelectedItem);
}
Run Code Online (Sandbox Code Playgroud)