关于c#:哪个.Net集合可一次添加多个对象并得到通知?

关于c#:哪个.Net集合可一次添加多个对象并得到通知?

Which .Net collection for adding multiple objects at once and getting notified?

正在考虑System.Collections.ObjectModel ObservableCollection<T>类。这个很奇怪,因为

  • 它有一个只需要一项的添加方法。没有AddRange或等效项。
  • Notification事件参数具有NewItems属性,该属性是一个IList(对象的..不是T)

我这里需要将一批对象添加到集合中,并且侦听器还将批处理作为通知的一部分。我是否缺少ObservableCollection的东西?还有另一个符合我要求的课程吗?

更新:不想自己动手。我必须构建添加/删除/更改等。很多东西。

相关问题:
https://stackoverflow.com/questions/670577/observablecollection-doesnt-support-addrange-method-so-i-get-notified-for-each


似乎INotifyCollectionChanged接口允许在添加多个项目时进行更新,所以我不确定为什么ObservableCollection<T>没有AddRange。您可以为AddRange设置扩展方法,但这将为添加的每个项目导致一个事件。如果那是不可接受的,则您应该能够从ObservableCollection<T>继承,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MyObservableCollection< T > : ObservableCollection< T >
{
    // matching constructors ...

    bool isInAddRange = false;

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        // intercept this when it gets called inside the AddRange method.
        if (!isInAddRange)
            base.OnCollectionChanged(e);
    }


    public void AddRange(IEnumerable< T > items)
    {
         isInAddRange = true;
         foreach (T item in items)
            Add(item);
         isInAddRange = false;

         var e = new NotifyCollectionChangedEventArgs(
             NotifyCollectionChangedAction.Add,
             items.ToList());
         base.OnCollectionChanged(e);
    }
}

这个想法和fryguybob的想法是一样的-有点奇怪,ObservableCollection是半完成的。这个东西的事件args甚至都没有使用Generics ..让我使用IList(就是这样。..昨天:)
经过测试的代码段如下...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace MyNamespace
{
    public class ObservableCollectionWithBatchUpdates< T > : ObservableCollection< T >
    {
        public void AddRange(ICollection< T > obNewItems)
        {
            IList< T > obAddedItems = new List< T >();
            foreach (T obItem in obNewItems)
            {
                Items.Add(obItem);
                obAddedItems.Add(obItem);
            }
            NotifyCollectionChangedEventArgs obEvtArgs = new NotifyCollectionChangedEventArgs(
               NotifyCollectionChangedAction.Add,
               obAddedItems as System.Collections.IList);
            base.OnCollectionChanged(obEvtArgs);
        }

    }
}

如果您使用上述任何一种发送添加范围命令并将observablecolletion绑定到listview的实现,都会收到此讨厌的错误。

1
2
3
4
5
NotSupportedException
   at System.Windows.Data.ListCollectionView.ValidateCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e)
   at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)

我使用的实现使用Reset事件,该事件在WPF框架周围更加均匀地实现:

1
2
3
4
5
6
7
    public void AddRange(IEnumerable< T > collection)
    {
        foreach (var i in collection) Items.Add(i);
        OnPropertyChanged("Count");
        OnPropertyChanged("Item[]");
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

System.Collections.ObjectModel.Collection<T>不仅是一个不错的选择,而且在帮助文档中,有一个示例说明如何重写其各种受保护的方法以获取通知。 (向下滚动到示例2。)


我已经多次看到这种问题,我想知道为什么连微软都在其他地方已经推广了更好的collection的地方推广ObservableCollection。

BindingList< T >

这允许您关闭通知并执行批量操作,然后打开通知。


另一个类似于CollectionView模式的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class DeferableObservableCollection< T > : ObservableCollection< T >
{
    private int deferLevel;

    private class DeferHelper< T > : IDisposable
    {
        private DeferableObservableCollection< T > owningCollection;
        public DeferHelper(DeferableObservableCollection< T > owningCollection)
        {
            this.owningCollection = owningCollection;
        }

        public void Dispose()
        {
            owningCollection.EndDefer();
        }
    }

    private void EndDefer()
    {
        if (--deferLevel <= 0)
        {
            deferLevel = 0;
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }

    public IDisposable DeferNotifications()
    {
        deferLevel++;
        return new DeferHelper< T >(this);
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (deferLevel == 0) // Not in a defer just send events as normally
        {
            base.OnCollectionChanged(e);
        } // Else notify on EndDefer
    }
}

如果您想从某种集合中继承,最好从System.Collections.ObjectModel.Collection继承,因为它提供了用于重写的虚拟方法。如果走那条路线,您将不得不遮蔽List之外的方法。

我不知道任何提供此功能的内置集合,但我欢迎对此进行纠正:)


从List < T >继承并重写Add()和AddRange()方法引发事件吗?


要快速添加,可以使用:

1
((List<Person>)this.Items).AddRange(NewItems);

使用C#和VB中的AddRange,RemoveRange和Replace range方法查看Observable集合。

在VB中:INotifyCollectionChanging实现。


推荐阅读

    linux新硬件添加命令?

    linux新硬件添加命令?,系统,设备,数据,业务,服务,盘前,信息,密码,名字,硬盘,

    linux命令添加一个组?

    linux命令添加一个组?,密码,系统,管理,代码,用户组,用户,命令,新增,文件,目

    linux多个窗口命令?

    linux多个窗口命令?,工具,系统,命令,首页,技术,情况,终端,窗口,脚本,界面,Lin

    linux脚本多个命令?

    linux脚本多个命令?,系统,工作,标准,服务,命令,软件,管理,连续,电脑,设备,lin

    linux添加快捷命令?

    linux添加快捷命令?,软件,名称,较大,第一,发行,命令,终端,快捷键,窗口,方法,

    linux命令添加文件?

    linux命令添加文件?,工作,简介,数据,系统,文件,命令,操作,文件名,内容,终端,l

    linux添加自启命令?

    linux添加自启命令?,服务,状态,密码,系统,脚本,第三,人员,标准,在线,实时,Pyt

    linux自启命令添加?

    linux自启命令添加?,服务,系统,工具,第三,第一,代码,密码,标准,项目,实时,lin

    linux无效对象的命令?

    linux无效对象的命令?,软件,系统,单位,网络,管理,术语,检测,电脑,环境,风险,l

    linux命令怎么添加组?

    linux命令怎么添加组?,系统,密码,管理,用户,电脑,代码,新增,用户组,命令,账

    linux添加账户的命令?

    linux添加账户的命令?,密码,系统,信息,用户,软件,地址,状态,数字,命令,用户

    linux系统添加命令?

    linux系统添加命令?,系统,密码,工作,简介,术语,地址,命令,文件,目录,用户,Lin

    linux添加一条命令?

    linux添加一条命令?,项目,数据,工具,材料,电脑,系统,密码,软件,环境,管理,假

    添加字符串命令linux?

    添加字符串命令linux?,情况,名称,文件,位置,名字,地方,连续,信息,命令,内容,L

    命令行添加linux启动?

    命令行添加linux启动?,系统,软件,工具,环境,初级,地址,发行,命令,目录,终端,l

    手机添加linux命令行?

    手机添加linux命令行?,系统,手机,环境,设备,网络,工作,信息,资料,检测,密码,

    linux多个命令输入?

    linux多个命令输入?,系统,工具,工作,命令,电脑,地址,信息,软件,服务,连续,Lin

    添加网卡linux命令?

    添加网卡linux命令?,网络,地址,信息,状态,系统,网卡,技术指标,材料,下来,服

    linux添加命令参数?

    linux添加命令参数?,系统,管理,工作,基础,命令,情况,网络,工具,代码,环境,别

    linux添加命令权限?

    linux添加命令权限?,密码,系统,权限,数字,地址,文件,命令,用户,表示,文件夹,