TreeViewItem.ItemContainerGenerator return 更改 ItemsSource 后为空
TreeViewItem.ItemContainerGenerator return null after change ItemsSource
在 TreeViewItem_OnExpanded 事件中,我有以下代码。
var expandedTreeViewItem = e.OriginalSource as TreeViewItem;
var child = expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
expandedTreeViewItem.ItemsSource = // Update ItemsSource
var child = expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
在更改扩展树视图项的ItemSource之前获取child时没有问题,但是在更改ItemSource之后,child将为null。
ContainerFromItem(item)中的item在ItemSource改变前后相同且存在。代码的其他部分工作正常。 ItemSource 更改后如何获取元素?
TreeViewItem_OnExpanded 事件代码
private void TreeViewItem_OnExpanded(object sender, RoutedEventArgs e)
{
var expandedTreeViewItem = e.OriginalSource as TreeViewItem;
var directoryInfo = expandedTreeViewItem?.Items[0] as DirectoryInfoModel;
if (expandedTreeViewItem == null || directoryInfo?.HasChild == false) return;
_folderExplorerViewModel.GetDirectories(directoryInfo?.DirectoryInfo, directoryInfo?.SubDirectoriesCollection);
expandedTreeViewItem.ItemsSource = directoryInfo?.SubDirectoriesCollection;
var expandedItemHeader = expandedTreeViewItem?.Template.FindName("PART_Header", expandedTreeViewItem) as ContentPresenter;
var expandedItemCheckBox = expandedItemHeader?.ContentTemplate.FindName("CheckBoxFolderItem", expandedItemHeader) as CheckBox;
foreach (var item in expandedTreeViewItem.Items)
{
var childItem = expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
var childHeader = childItem?.Template.FindName("PART_Header", childItem) as ContentPresenter;
var childCheckBox = childHeader?.ContentTemplate.FindName("CheckBoxFolderItem", childHeader) as CheckBox;
if (childCheckBox != null && expandedItemCheckBox != null)
{
childCheckBox.IsChecked = expandedItemCheckBox.IsChecked;
}
}
}
ItemesSource 改变后使用时,childItem 始终为空。但在此之前,它有效。
非常感谢。
我找到了答案here。在 TreeViewItem_OnExpanded 事件未完成其工作之前,尚未在 UI 中创建新项目,因此 ItemContainerGenerator return 为空。我在其 class 中将 expandedTreeViewItem 设为常规,并为每个展开的树视图项目添加了 LayoutUpdated 事件处理程序,然后在 LayoutUpdated 事件中,我可以访问 ItemSource 添加的新项目。我不知道这是否是标准方式,但现在它可以在没有任何 returning null 的情况下工作。
private TreeViewItem _expandedTreeViewItem;
private void TreeViewItem_OnExpanded(object sender, RoutedEventArgs e)
{
_expandedTreeViewItem = e.OriginalSource as TreeViewItem;
var directoryInfo = _expandedTreeViewItem?.Items[0] as DirectoryInfoModel;
if (_expandedTreeViewItem == null || directoryInfo?.HasChild == false) return;
_folderExplorerViewModel.GetDirectories(directoryInfo?.DirectoryInfo, directoryInfo?.SubDirectoriesCollection);
_expandedTreeViewItem.ItemsSource = directoryInfo?.SubDirectoriesCollection;
_expandedTreeViewItem.LayoutUpdated += ExpandedTreeViewItem_OnLayoutUpdated;
}
private void ExpandedTreeViewItem_OnLayoutUpdated(object sender, EventArgs e)
{
var expandedItemHeader = _expandedTreeViewItem?.Template.FindName("PART_Header", _expandedTreeViewItem) as ContentPresenter;
var expandedItemCheckBox = header?.ContentTemplate.FindName("CheckBoxFolderItem", header) as CheckBox;
foreach (var item in _expandedTreeViewItem.Items)
{
var childItem = _expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
var childHeader = childItem?.Template.FindName("PART_Header", childItem) as ContentPresenter;
var childCheckBox = childHeader?.ContentTemplate.FindName("CheckBoxFolderItem", childHeader) as CheckBox;
if (childCheckBox != null && expandedItemCheckBox != null)
{
childCheckBox.IsChecked = expandedItemCheckBox.IsChecked;
}
}
}
在 TreeViewItem_OnExpanded 事件中,我有以下代码。
var expandedTreeViewItem = e.OriginalSource as TreeViewItem;
var child = expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
expandedTreeViewItem.ItemsSource = // Update ItemsSource
var child = expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
在更改扩展树视图项的ItemSource之前获取child时没有问题,但是在更改ItemSource之后,child将为null。
ContainerFromItem(item)中的item在ItemSource改变前后相同且存在。代码的其他部分工作正常。 ItemSource 更改后如何获取元素?
TreeViewItem_OnExpanded 事件代码
private void TreeViewItem_OnExpanded(object sender, RoutedEventArgs e)
{
var expandedTreeViewItem = e.OriginalSource as TreeViewItem;
var directoryInfo = expandedTreeViewItem?.Items[0] as DirectoryInfoModel;
if (expandedTreeViewItem == null || directoryInfo?.HasChild == false) return;
_folderExplorerViewModel.GetDirectories(directoryInfo?.DirectoryInfo, directoryInfo?.SubDirectoriesCollection);
expandedTreeViewItem.ItemsSource = directoryInfo?.SubDirectoriesCollection;
var expandedItemHeader = expandedTreeViewItem?.Template.FindName("PART_Header", expandedTreeViewItem) as ContentPresenter;
var expandedItemCheckBox = expandedItemHeader?.ContentTemplate.FindName("CheckBoxFolderItem", expandedItemHeader) as CheckBox;
foreach (var item in expandedTreeViewItem.Items)
{
var childItem = expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
var childHeader = childItem?.Template.FindName("PART_Header", childItem) as ContentPresenter;
var childCheckBox = childHeader?.ContentTemplate.FindName("CheckBoxFolderItem", childHeader) as CheckBox;
if (childCheckBox != null && expandedItemCheckBox != null)
{
childCheckBox.IsChecked = expandedItemCheckBox.IsChecked;
}
}
}
ItemesSource 改变后使用时,childItem 始终为空。但在此之前,它有效。
非常感谢。
我找到了答案here。在 TreeViewItem_OnExpanded 事件未完成其工作之前,尚未在 UI 中创建新项目,因此 ItemContainerGenerator return 为空。我在其 class 中将 expandedTreeViewItem 设为常规,并为每个展开的树视图项目添加了 LayoutUpdated 事件处理程序,然后在 LayoutUpdated 事件中,我可以访问 ItemSource 添加的新项目。我不知道这是否是标准方式,但现在它可以在没有任何 returning null 的情况下工作。
private TreeViewItem _expandedTreeViewItem;
private void TreeViewItem_OnExpanded(object sender, RoutedEventArgs e)
{
_expandedTreeViewItem = e.OriginalSource as TreeViewItem;
var directoryInfo = _expandedTreeViewItem?.Items[0] as DirectoryInfoModel;
if (_expandedTreeViewItem == null || directoryInfo?.HasChild == false) return;
_folderExplorerViewModel.GetDirectories(directoryInfo?.DirectoryInfo, directoryInfo?.SubDirectoriesCollection);
_expandedTreeViewItem.ItemsSource = directoryInfo?.SubDirectoriesCollection;
_expandedTreeViewItem.LayoutUpdated += ExpandedTreeViewItem_OnLayoutUpdated;
}
private void ExpandedTreeViewItem_OnLayoutUpdated(object sender, EventArgs e)
{
var expandedItemHeader = _expandedTreeViewItem?.Template.FindName("PART_Header", _expandedTreeViewItem) as ContentPresenter;
var expandedItemCheckBox = header?.ContentTemplate.FindName("CheckBoxFolderItem", header) as CheckBox;
foreach (var item in _expandedTreeViewItem.Items)
{
var childItem = _expandedTreeViewItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
var childHeader = childItem?.Template.FindName("PART_Header", childItem) as ContentPresenter;
var childCheckBox = childHeader?.ContentTemplate.FindName("CheckBoxFolderItem", childHeader) as CheckBox;
if (childCheckBox != null && expandedItemCheckBox != null)
{
childCheckBox.IsChecked = expandedItemCheckBox.IsChecked;
}
}
}