Wpf 延迟项的可见性控件项
我有一个场景,其中我希望在ItemsControl中显示许多项。由于项目的布局方式(使用画布),我无法使用标准的虚拟化面板,因此加载控件需要很长时间 我想知道如何分批加载这些项目,而不是一次性加载所有项目 例如,如果我使用的是一个ListBox,它的itemsSource设置为某个大列表,我如何才能批量创建ListBoxItems,比如说10个项目,将剩余的延迟到下一个Dispatcher事件(后台或AppIdle)上运行 通过让ItemsSource成为一个可观察的集合,随着每个新批处理的增长,这个问题可以很容易地从ViewModel中解决,但是我想在视图级别添加它Wpf 延迟项的可见性控件项,wpf,visibility,itemscontrol,deferred,Wpf,Visibility,Itemscontrol,Deferred,我有一个场景,其中我希望在ItemsControl中显示许多项。由于项目的布局方式(使用画布),我无法使用标准的虚拟化面板,因此加载控件需要很长时间 我想知道如何分批加载这些项目,而不是一次性加载所有项目 例如,如果我使用的是一个ListBox,它的itemsSource设置为某个大列表,我如何才能批量创建ListBoxItems,比如说10个项目,将剩余的延迟到下一个Dispatcher事件(后台或AppIdle)上运行 通过让ItemsSource成为一个可观察的集合,随着每个新批处理的增长
我也不希望使用ItemContainers可见性属性来实现它,因为它很可能已经被使用了。这将取决于数据来自何处。但我可以告诉你,从视图加载只是一个糟糕的计划
/// <summary>
/// Initializes a new instance of the
/// <see cref="ObservableCollectionEx{T}"/> class.
/// </summary>
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
#region Constructors
/// <summary>
/// Initializes a new instance of the
/// <see cref="ObservableCollectionEx{T}" /> class.
/// </summary>
public ObservableCollectionEx()
{
}
///
/// Initializes a new instance of the
/// class.
///
///The collection.
public ObservableCollectionEx(IEnumerable<T> collection) : this()
{
this.AddRange(collection);
}
#endregion
#region Events
/// <summary>
/// Source: New Things I Learned
/// Title: Have worker thread update ObservableCollection that is bound to a ListCollectionView
/// http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx
/// Note: Improved for clarity and the following of proper coding standards.
/// </summary>
/// <param name="e"></param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
// Use BlockReentrancy
using (BlockReentrancy())
{
var eventHandler = CollectionChanged;
if (eventHandler == null) return;
// Only proceed if handler exists.
Delegate[] delegates = eventHandler.GetInvocationList();
// Walk through invocation list.
foreach (var @delegate in delegates)
{
var handler = (NotifyCollectionChangedEventHandler)@delegate;
var currentDispatcher = handler.Target as DispatcherObject;
// If the subscriber is a DispatcherObject and different thread.
if ((currentDispatcher != null) && (!currentDispatcher.CheckAccess()))
{
// Invoke handler in the target dispatcher's thread.
currentDispatcher.Dispatcher.Invoke(
DispatcherPriority.DataBind, handler, this, e);
}
else
{
// Execute as-is
handler(this, e);
}
}
}
}
/// <summary>
/// Overridden NotifyCollectionChangedEventHandler event.
/// </summary>
public override event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion
}
//
///初始化的新实例
///班级。
///
公共类ObservableCollectionEx:ObservableCollection
{
#区域构造函数
///
///初始化的新实例
///班级。
///
公共可观测集合
{
}
///
///初始化的新实例
///班级。
///
///收藏。
公共ObservableCollectionEx(IEnumerable集合):this()
{
此.AddRange(集合);
}
#端区
#地区活动
///
///资料来源:我学到的新东西
///标题:让工作线程更新绑定到ListCollectionView的ObservableCollection
/// http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx
///注:为了清晰和遵循正确的编码标准而改进。
///
///
CollectionChanged上的受保护覆盖无效(NotifyCollectionChangedEventArgs e)
{
//使用块重入
使用(BlockReentrancy())
{
var eventHandler=CollectionChanged;
if(eventHandler==null)返回;
//仅当处理程序存在时才继续。
Delegate[]delegates=eventHandler.GetInvocationList();
//浏览调用列表。
foreach(代理中的var@delegate)
{
var handler=(NotifyCollectionChangedEventHandler)@delegate;
var currentDispatcher=handler.Target作为DispatcherObject;
//如果订阅服务器是DispatcherObject和其他线程。
if((currentDispatcher!=null)&;(!currentDispatcher.CheckAccess())
{
//在目标调度程序的线程中调用处理程序。
currentDispatcher.Dispatcher.Invoke(
DispatcherPriority.DataBind,handler,this,e);
}
其他的
{
//按原样执行
处理者(本,e);
}
}
}
}
///
///已重写NotifyCollectionChangedEventHandler事件。
///
公共覆盖事件NotifyCollectionChangedEventHandler CollectionChanged;
#端区
}
正如我在问题中提到的,我知道我可以很容易地从ViewModel完成这项工作。