【问题标题】:How to change VisualState of UserControl used as ItemTemplate in ListView如何更改在 ListView 中用作 ItemTemplate 的 UserControl 的 VisualState
【发布时间】:2015-01-07 06:43:27
【问题描述】:

我有一个 UserControl 定义了一些 VisualStates

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

我将它用作我的 ListViewItemTemplate。 When item from ListView is selected, I also want to change the VisualState of the DataTemplate.目前我有这样的方法:

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 ListViewItemnull,因此会引发异常。

有没有其他/更好的方法来改变使用的DataTemplateVisualState

【问题讨论】:

  • 所以您希望列表视图项设置的视觉状态也由您的 UserControl 中的 VSM 自动继承以反映它?只是为了确保我理解。
  • @ChrisW。是的,这是对的。例如,我的 UserControl 中有一个 TextBlock 并且视觉状态管理器将其更改为前景色。选择列表项后,我希望它触发。
  • 而且你不能说它在哪些情况下不起作用?如果你发现了这一点,你很可能能够修复它。如果您提供一些示例解决方案,我可以检查一下。另外,我会使用(cast) 而不是as
  • @yasen 正如我所观察到的,当我没有通过触摸屏幕来选择项目时,问题是(并非总是如此),而是当我从代码中选择项目时 - 例如通过将它们添加到 SelectedItems i> 或设置 IsSelected。明天我会尝试构建一个样本并给你一个标志。
  • 您的ListView 需要虚拟化吗?它需要处理大量数据吗?

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


【解决方案1】:

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

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

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

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

首先仍然需要你现有的代码,你只需要做一个空检查,如果项目容器是空的,什么都不做。

然后,您需要订阅ListViewContainerContentChanging 事件。这会在项目容器被加载时触发。所以基本上,您检查此处加载的项目是否是选定项目之一。如果是,则更改其视觉状态。像这样 -

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
    }
}

【讨论】:

  • 看起来很不错的信息,可以解释一切。我稍后会尝试并得到结果。
  • 这绝对是问题所在,现在一切正常。谢谢你的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2016-11-29
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多