C# 如何更改在ListView中用作ItemTemplate的UserControl的VisualState

C# 如何更改在ListView中用作ItemTemplate的UserControl的VisualState,c#,windows,xaml,windows-phone-8.1,C#,Windows,Xaml,Windows Phone 8.1,我有一个用户控件,其中定义了一些可视状态: 我将它用作ListView的ItemTemplate。当选中ListView中的项时,我还想更改DataTemplate的VisualState。目前我有这样一种方法: private void list\u SelectionChanged(对象发送者,selectionchangedventargs e) { ListView ListView=发件人作为ListView; foreach(e.AddedItems中的变量项) VisualSt

我有一个用户控件,其中定义了一些可视状态:


我将它用作ListView的ItemTemplate。当选中ListView中的项时,我还想更改DataTemplate的VisualState。目前我有这样一种方法:

private void list\u SelectionChanged(对象发送者,selectionchangedventargs e)
{
ListView ListView=发件人作为ListView;
foreach(e.AddedItems中的变量项)
VisualStateManager.GoToState((listView.ContainerFromItem(item)作为ListViewItem)。ContentTemplateRoot作为myControl,“Selected”,false);
}
它似乎可以工作,但在某些情况下,
(listView.ContainerFromItem(item)as ListViewItem
为空,因此引发异常


是否有其他/更好的方法来更改所用数据模板的VisualState?

项容器(即
ListViewItem
)是
null
是因为
ListView
的默认面板
ItemsStackPanel
是一个基于像素的UI虚拟化面板,它仅在项目位于或接近当前视口时才渲染项目

由于您在代码中设置了所选项目,这些项目可能不会被呈现,它们的容器将返回为
null

一个简单的修复方法是用一个普通的
StackPanel
替换
ItemsStackPanel
,但是这样做会破坏内置的虚拟化

这是另一个不修改面板的解决方案

首先,仍然需要现有代码,您只需要执行null检查,如果项目容器为null,则什么也不做

然后,您需要订阅
ListView
ContainerContentChangeing
事件。这会在项目容器加载时触发。因此,基本上,您会检查此处加载的项目是否为所选项目之一。如果是,则更改其视觉状态。类似于下面的内容-

private void MyListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    if (this.MyListView.SelectedItems.Contains(args.Item))
    {
        // get the container
        var container = (ListViewItem)args.ItemContainer; 

        // do your visual state change here, when the container was previously null
    }
}

因此,您希望listview项设置的visualstate也被UserControl中的VSM自动继承以反映它吗?只是为了确保我理解。@ChrisW。是的,没错。例如,我的UserControl中有一个TextBlock,而visual state manager更改了它的前景色。选择列表项后,我希望它触发。a你不能说在哪种情况下它不起作用?如果你发现了,你很可能能够修复它。如果你提供一些示例解决方案,我可以检查它。此外,我会使用
(cast)
,而不是
,因为我观察到问题所在(并非总是如此)当我不是通过触摸屏幕来选择项目,而是从代码中选择项目时-例如,通过将它们添加到SelectedItems或setting IsSelected。我明天将尝试构建一个示例并给您一个提示。您的
列表视图是否需要虚拟化?它是否需要处理大量数据?看起来像是一堆很好的信息,这将我会解释一切的。我会稍后再试,然后返回结果。这肯定是问题所在,现在一切正常。谢谢你的帮助。