Wpf 获取ListView项目容器的好方法是什么?

Wpf 获取ListView项目容器的好方法是什么?,wpf,uwp,Wpf,Uwp,我的问题是针对UWP,但在WPF中的解决方案可能是相同的,所以我也标记了它 我试图在自定义GridView和ListView中实现扩展方法,以便在选择更改时,所选项目将始终平滑地动画显示到视图中 扩展方法非常有效。然而,获取UIElement容器来发送它并不是很好 Items绑定到ViewModel中的集合。所以ListView.Items不是UIElements,而是数据对象。我需要SelectedItem对应的UIElement容器 首先,我尝试了这个: void ListView_Sele

我的问题是针对UWP,但在WPF中的解决方案可能是相同的,所以我也标记了它

我试图在自定义GridView和ListView中实现扩展方法,以便在选择更改时,所选项目将始终平滑地动画显示到视图中

扩展方法非常有效。然而,获取UIElement容器来发送它并不是很好

Items绑定到ViewModel中的集合。所以ListView.Items不是UIElements,而是数据对象。我需要SelectedItem对应的UIElement容器

首先,我尝试了这个:

void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (_scrollViewer != null && this.ItemsPanelRoot != null && this.Items.Count > 0)
    {
        var selectedListViewItem = this.ItemsPanelRoot.Children[this.SelectedIndex];
        if (selectedListViewItem != null)
        {
            _scrollViewer.ScrollToElement(selectedListViewItem);
        }
    }
}
这在一开始是有效的,但实际上并不好。随着布局的动态更新,“ListView.ItemsPanelRoot.Children”的索引最终开始偏离“ListView.Items”

然后我尝试了这个,到目前为止似乎效果不错:

void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (_scrollViewer != null && this.Items.Count > 0)
    {
        var selectedListViewItem = this.ItemsPanelRoot.FindDescendants<ListViewItem>()
                        .Where(x => x.Content == this.SelectedItem).FirstOrDefault();
        if (selectedListViewItem != null)
        {
            _scrollViewer.ScrollToElement(selectedListViewItem);
        }
        else
        {
            throw new Exception();
        }
    }
}
问题是,每次执行该查询似乎花费极高,而且也不安全,因为还不能保证容器可用。我希望我错过了一些东西,希望有一个合适的方法来做到这一点

注意:“FindDescents”是Windows UI Toolkit中的一个扩展方法,与VisualTreeHelper的功能相同。

Items控件有一个属性,该属性保存一个项​容器​生成器对象,可用于获取项目和项目索引等的项目容器

例如

在UWP中,ContainerFromItem和类似的方法也可以直接在ItemsControl类中使用,因此您可以编写

var container = listView.ContainerFromItem(item);

您可以查看ListView的。在UWP中,ItemsControl.Lol-yup中也有一个方法,这正是我想要的。我不知道我怎么会在文档中漏掉它,我想我期待的是一个属性而不是一个方法。非常感谢,请随意回答。
var container = listView.ContainerFromItem(item);