将更多项目添加到NavigationView需要很长时间



我想向NavigationView添加1500个项目我使用了actionblock,但它仍然很慢,大约需要10秒才能在ui 中添加项目

private ObservableCollection<NavigationViewItem> data;
TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
private void DoSomethingWithCustomer(NavigationViewItem c)
{
Task.Run(() =>
{
data.Add(c);
}).ContinueWith(x =>
{
NavigationView.MenuItemsSource = data;
}, taskScheduler);
}

和:

ActionBlock<NavigationViewItem> action = new ActionBlock<NavigationViewItem>(DoSomethingWithCustomer, new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount
});
var coll = System.IO.Directory.EnumerateDirectories("D:\Pic\Art");
foreach (var customer in coll)
{
var item = new NavigationViewItem { Content = new DirectoryInfo(customer).Name };
action.Post(item);
}
action.Complete();
await action.Completion;

我试过了,EnumerateDirectories在不到1秒的时间内完成了。但向ui 添加项目需要很长时间

进程很慢,因为ObservableCollection实现了INotifyCollectionChanged接口,该接口有一个名为CollectionChanged的事件。每当向集合中添加项目并且UI(NavigationView(正在侦听时,就会触发此事件。

这意味着,每次添加项目时,UI都必须对其进行渲染,从而使添加数百或数千个项目的过程变得缓慢。

您最好实现自己版本的ObservableCollection,它会延迟触发该事件,直到添加所有项目。这里可以找到一个例子:https://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/

public class RangeObservableCollection<T> : ObservableCollection<T>
{
private bool _suppressNotification = false;

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!_suppressNotification)
base.OnCollectionChanged(e);
}

public void AddRange(IEnumerable<T> list)
{
if (list == null)
throw new ArgumentNullException("list");

_suppressNotification = true;

foreach (T item in list)
{
Add(item);
}
_suppressNotification = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}

最新更新