【发布时间】:2018-09-18 02:27:18
【问题描述】:
我最近一直在使用 WPF 树视图,当用户使用在支持对象。
目前我的方法是使用这个答案中的方法:https://stackoverflow.com/a/34620549/800318
private void FocusTreeViewNode(TreeViewEntry node)
{
if (node == null) return;
var nodes = (IEnumerable<TreeViewEntry>)LeftSide_TreeView.ItemsSource;
if (nodes == null) return;
var stack = new Stack<TreeViewEntry>();
stack.Push(node);
var parent = node.Parent;
while (parent != null)
{
stack.Push(parent);
parent = parent.Parent;
}
var generator = LeftSide_TreeView.ItemContainerGenerator;
while (stack.Count > 0)
{
var dequeue = stack.Pop();
LeftSide_TreeView.UpdateLayout();
var treeViewItem = (TreeViewItem)generator.ContainerFromItem(dequeue);
if (stack.Count > 0)
{
treeViewItem.IsExpanded = true;
}
else
{
if (treeViewItem == null)
{
//This is being triggered when it shouldn't be
Debugger.Break();
}
treeViewItem.IsSelected = true;
}
treeViewItem.BringIntoView();
generator = treeViewItem.ItemContainerGenerator;
}
}
TreeViewEntry 是我的后备数据类型,它具有对其父节点的引用。 Leftside_TreeView 是绑定到我的对象列表的虚拟化 TreeView。关闭虚拟化不是一种选择,因为关闭它的性能真的很差。
当我搜索一个对象并找到支持数据对象时,我调用此 FocusTreeViewNode() 方法,并将该对象作为其参数。它通常会在第一次调用时工作,选择对象并将其显示在视图中。
在第二次进行搜索时,要选择的节点被传入,但是当堆栈被清空时 ContainerFromItem() 调用(因此它试图为对象本身生成容器)返回 null。当我调试它时,我可以在 ContainerGenerator 的项目列表中看到我正在搜索的对象,但由于某种原因它没有被返回。我查了所有与 UpdateLayout() 和其他东西有关的东西,但我想不通。
容器中的某些对象即使在父节点显示后也可能不在页面上 - 例如。扩展器下有 250 个项目,并且一次只渲染 60 个。这可能是一个问题吗?
更新
这是一个示例项目,它制作了一个显示此问题的虚拟化树视图。 https://github.com/Mgamerz/TreeViewVirtualizingErrorDemo
在 VS 中构建它,然后在搜索框中输入类似 4 的内容。按几次搜索它会抛出一个异常说容器为空,即使你打开 generator 对象你可以清楚地看到它在发电机。
【问题讨论】:
-
你有一个小的复制项目吗?
-
是的,我相信我可以创建一个,给我几个小时,因为我正在做的那个太复杂了,无法缩小。
-
完成 - 添加了一个 github 项目的链接来展示该问题