在ObservableCollection上实现AddRange,并对DataBinding提供适当的支持
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在ObservableCollection上实现AddRange,并对DataBinding提供适当的支持相关的知识,希望对你有一定的参考价值。
我想我自己的ObservableCollection
后代支持AddRange
方法。这是我目前拥有的:
public class ObservableCollectionPlus<T> : ObservableCollection<T>
{
public void InsertRange(IEnumerable<T> items)
{
this.CheckReentrancy();
foreach (var item in items) Items.Add(item);
var type = NotifyCollectionChangedAction.Reset;
var colChanged = new NotifyCollectionChangedEventArgs(type);
var countChanged = new PropertyChangedEventArgs("Count");
OnPropertyChanged(countChanged);
OnCollectionChanged(colChanged);
}
}
我对这里发生的事情并不了解,为什么这些事件会被提升。这是我在对google和stackoverflow进行一些研究后组装的一个解决方案。
现在,如果我将我的类的一个实例绑定到LongListSelector
然后,在通过InsertRange
动态添加项目到ObservableCollectionPlus
之后,绑定的LongListSelector
的滚动位置被发送到它的顶部。
如果我以这种标准方式添加项目:foreach (var item in items) collection.Add(item);
然后LongListSelector
的位置不会被移位。但是当然这样我得到的DataBinding通知开销是不受欢迎的。
显然,在我目前的解决方案中出现了问题。我怎样才能实现InsertRange
,它的行为与foreach (var item in items) collection.Add(item);
完全相同,但只会触发一次DataBinding通知,并且不会对绑定对象的滚动位置做出奇怪的事情?
这可能是因为你发送NotifyCollectionChangedAction.Reset
通知,也许只是NotifyCollectionChangedAction.Add
将工作,也许:)
public class ObservableRangeCollection<T> : ObservableCollection<T>
{
public void AddRange(IEnumerable<T> collection)
{
foreach (var i in collection)
{
Items.Add(i);
}
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));
}
}
我最近在一个项目中使用过这个......
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));
}
}
您在使用DataBinding时遇到的问题可能与您没有为Indexer(属性名称“Item []”)引发PropertyChanged这一事实有关,因为它发生在ObservableCollection according to the source code中。
您还可以查看James Montemagno here on GitHub对ObservableRangeCollection的一个很好的实现,它继承自ObservableColection,并包含AddRange和ReplaceRange方法以及DataBinding所需的所有PropertyChaged和CollectionChanged通知。
它花了我很多年,麻烦总是与传递给NotifyCollectionChangedEventArgs ctor的参数。根据行动,有许多不同的ctors采取不同的论点。以下似乎最终对我有用:https://github.com/lolluslollus/Utilz/blob/master/Utilz/SwitchableObservableCollection.cs
以上是关于在ObservableCollection上实现AddRange,并对DataBinding提供适当的支持的主要内容,如果未能解决你的问题,请参考以下文章