Alb*_*eld 8 wpf codeplex .net-3.5
用于WPF的虚拟化包装面板的选项不是很多.由于某种原因,MS决定不在标准库中发货.
如果有人能够如此大胆地为下面的codeplex项目的第一个工作项提供人群来源答案(和解释),我将不胜感激:
http://virtualwrappanel.codeplex.com/workitem/1
谢谢!
问题摘要:
我最近尝试过使用此项目中的虚拟化包装并遇到了一个错误.
重现步骤:
Debug.Assert失败(Debug.Assert(child == _children [childIndex],"生成了错误的子项");)在MeasureOverride中,继续执行会导致Cleanup方法中出现空异常[请参阅附件截图].
如果你能纠正这个问题,请告诉我.
谢谢,
AO
码:
http://virtualwrappanel.codeplex.com/SourceControl/list/changesets#
解释问题
您要求解释出现问题的原因以及如何解决问题的说明.到目前为止,没有人解释过这个问题 我会这样做的.
在带有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;
}
Run Code Online (Sandbox Code Playgroud)
这使InternalChildren集合与其他数据结构保持同步.
为什么不在这里调用AddInternalChild/InsertInternalChild
您可能想知道为什么在上面的代码中没有调用InsertInternalChild或AddInternalChild,特别是为什么处理Replace和Move不需要我们在OnItemsChanged期间添加新项目.
理解这一点的关键在于ItemContainerGenerator的工作方式.
当ItemContainerGenerator收到remove事件时,它立即处理所有事件:
另一方面,ItemContainerGenerator了解添加的项目通常是延迟的:
因此,来自InternalChildren集合的所有删除(包括属于Move或Replace的那些)必须在OnItemsChanged内完成,但添加可以(并且应该)延迟到下一个MeasureOverride.
OnItemsChanged 方法需要正确处理 args 参数。请参阅此问题以获取更多信息。复制该问题的代码,您需要像这样更新 OnItemsChanged:
protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) {
base.OnItemsChanged(sender, args);
_abstractPanel = null;
ResetScrollInfo();
// ...ADD THIS...
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;
}
}
Run Code Online (Sandbox Code Playgroud)