用于 WPF 的虚拟化包装面板的选项并不多。出于某种原因,MS 决定不在标准库中发布一个。
如果有人能如此大胆地为以下 codeplex 项目的第一个工作项提供众包答案(和解释),我将不胜感激:
http://virtualwrappanel.codeplex.com/workitem/1
谢谢!
问题总结:
我最近尝试使用这个项目中的虚拟化包装面板并遇到了一个错误。
重现步骤:
MeasureOverride 中的 Debug.Assert 失败 (Debug.Assert(child == _children[childIndex], "Wrong child was generated");),并且继续执行会导致 Cleanup 方法中出现空异常 [参见随附的屏幕截图]。
如果您能够纠正此问题,请告诉我。
谢谢,
AO
代码:
http://virtualwrappanel.codeplex.com/SourceControl/list/changesets#
alt text http://virtualwrappanel.codeplex.com/Project/Download/AttachmentDownload.ashx?ProjectName=virtualwrappanel&WorkItemId=1&FileAttachmentId=138959
最佳答案
问题解释
您要求解释发生了什么问题以及如何解决问题的说明。到目前为止,没有人解释这个问题。我会照办的。
在带有 VirtualizingWrapPanel 的 ListBox 中有五个单独的数据结构来跟踪项目,每个数据结构都以不同的方式:
从 ItemsSource 中删除项目时,必须通过所有数据结构传播此删除。下面是它的工作原理:
因此,InternalChildren 集合与其他四个集合不同步,从而导致出现错误。
问题解决方法
要解决此问题,请在 VirtualizingWrapPanel 的 OnItemsChanged 方法中的任意位置添加以下代码:
switch(args.Action)
{
case NotifyCollectionChangedAction.Remove:
case NotifyCollectionChangedAction.Replace:
RemoveInternalChildRange(args.Position.Index, args.ItemUICount);
break;
case NotifyCollectionChangedAction.Move:
RemoveInternalChildRange(args.OldPosition.Index, args.ItemUICount);
break;
}
这使 InternalChildren 集合与其他数据结构保持同步。
为什么这里不调用 AddInternalChild/InsertInternalChild
您可能想知道为什么上面的代码中没有调用 InsertInternalChild 或 AddInternalChild,尤其是为什么处理 Replace 和 Move 不需要我们在 OnItemsChanged 期间添加新项目。
理解这一点的关键在于 ItemContainerGenerator 的工作方式。
当 ItemContainerGenerator 收到一个 remove 事件时,它会立即处理所有事情:
另一方面,ItemContainerGenerator 获知添加了一个项目,所有内容通常都是延迟的:
因此,InternalChildren 集合中的所有删除(包括属于 Move 或 Replace 的部分)必须在 OnItemsChanged 内完成,但添加可以(并且应该)推迟到下一个 MeasureOverride。
关于wpf - 虚拟化 WPF Wrap 面板问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3356172/