如何更改在列表视图中用作项模板的用户控件的可视状态
本文关键字:用户 控件 状态 可视 何更改 列表 视图 | 更新日期: 2023-09-27 18:36:36
我有一个定义了一些 VisualState的用户控件:
<UserControl>
<Grid Height="50" HorizontalAlignment="Stretch">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<!-- more code -->
我将其用作我的列表视图的项模板。选择列表视图中的项时,我还想更改数据模板的可视状态。现在我有这样一个方法:
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
为空,因此会引发异常。
有没有其他/更好的方法来更改使用的数据模板的可视化状态?
项目容器(即 ListViewItem
) null
是因为ListView
的默认面板ItemsStackPanel
是基于像素的 UI 虚拟化面板,它仅在项目在当前视口中或接近当前视口时呈现项目。
由于您在代码中设置了选定的项,因此这些项可能不会呈现,它们的容器将作为null
返回。
一个简单的解决方法是用普通StackPanel
替换ItemsStackPanel
,但是这样做会破坏内置虚拟化。
这是另一种无需修改面板的解决方案。
首先你现有的代码还是需要的,你只需要做一个空检查,如果项容器是空的,干脆什么都不做。
然后,您需要订阅ListView
的ContainerContentChanging
事件。这将在加载项容器时触发。因此,基本上,您检查此处加载的项目是否是所选项目之一。如果是,则更改其视觉状态。像这样的东西——
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
}
}