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

时间:2015-01-07 06:43:28

标签: c# windows xaml windows-phone-8.1

我有一个 UserControl ,其中定义了一些 VisualStates

<UserControl>
  <Grid Height="50" HorizontalAlignment="Stretch">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="SelectionStates">
            <VisualState x:Name="Unselected"/>
            <VisualState x:Name="Selected">
            <!-- more code -->

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

private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  ListView listView = sender as ListView;
  foreach (var item in e.AddedItems)
    VisualStateManager.GoToState((listView.ContainerFromItem(item) as ListViewItem).ContentTemplateRoot as myControl, "Selected", false);
 }

它似乎有效,但在某些情况下(listView.ContainerFromItem(item) as ListViewItem null ,因此抛出异常。

是否有其他/更好的方法来更改已使用的 DataTemplate VisualState

1 个答案:

答案 0 :(得分:2)

项容器(即ListViewItem)为null的原因是ListView的默认面板ItemsStackPanel基于像素的UI虚拟化面板,仅在在当前视口中或靠近当前视口时呈现项目

由于您在代码中设置了所选项目,因此可能无法呈现这些项目,其容器将返回null

一个简单的解决方法是将ItemsStackPanel替换为普通StackPanel,但这样做会破坏内置虚拟化。

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

首先你的现有代码仍然需要,你只需要进行空检查,如果项容器为空,就什么都不做。

然后,您需要订阅ListView的{​​{1}}事件。当项目容器加载时会触发。所以基本上,你检查这里加载的项目是否是所选项目之一。如果是,则改变其视觉状态。像这样的东西 -

ContainerContentChanging