ObservableCollection 不支持 AddRange 方法,因此我会收到添加的每个项目的通知,除了 INotifyCollectionChanging 之外?

2023-12-29

我希望能够添加一个范围并获得整个批量的更新。

我还希望能够在操作完成之前取消该操作(即除了“更改”之外的集合更改)。


相关问题哪个 .Net 集合可用于一次添加多个对象并获得通知? https://stackoverflow.com/questions/57020/which-net-collection-for-adding-multiple-objects-at-once-and-getting-notified


请参阅更新和优化的C# 7版本 https://stackoverflow.com/a/45364074/75500。我不想删除 VB.NET 版本,所以我只是将其发布在单独的答案中。

前往更新版本 https://stackoverflow.com/a/45364074/75500

好像不支持,我自己实现的,仅供参考,希望对你有帮助:

我更新了 VB 版本,从现在开始,它会在更改集合之前引发一个事件,这样您就可以后悔(当与DataGrid, ListView还有更多,您可以向用户显示“您确定吗”确认),更新的 VB 版本位于此消息的底部.

请接受我的歉意,屏幕太窄,无法包含我的代码,我也不喜欢它。

VB.NET:

Imports System.Collections.Specialized

Namespace System.Collections.ObjectModel
    ''' <summary>
    ''' Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    Public Class ObservableRangeCollection(Of T) : Inherits System.Collections.ObjectModel.ObservableCollection(Of T)

        ''' <summary>
        ''' Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
        ''' </summary>
        Public Sub AddRange(ByVal collection As IEnumerable(Of T))
            For Each i In collection
                Items.Add(i)
            Next
            OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
        End Sub

        ''' <summary>
        ''' Removes the first occurence of each item in the specified collection from ObservableCollection(Of T).
        ''' </summary>
        Public Sub RemoveRange(ByVal collection As IEnumerable(Of T))
            For Each i In collection
                Items.Remove(i)
            Next

            OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
        End Sub

        ''' <summary>
        ''' Clears the current collection and replaces it with the specified item.
        ''' </summary>
        Public Sub Replace(ByVal item As T)
            ReplaceRange(New T() {item})
        End Sub
        ''' <summary>
        ''' Clears the current collection and replaces it with the specified collection.
        ''' </summary>
        Public Sub ReplaceRange(ByVal collection As IEnumerable(Of T))
            Dim old = Items.ToList
            Items.Clear()
            For Each i In collection
                Items.Add(i)
            Next
            OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
        End Sub

        ''' <summary>
        ''' Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            MyBase.New()
        End Sub
        ''' <summary>
        ''' Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection.
        ''' </summary>
        ''' <param name="collection">collection: The collection from which the elements are copied.</param>
        ''' <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception>
        Public Sub New(ByVal collection As IEnumerable(Of T))
            MyBase.New(collection)
        End Sub
    End Class   

End Namespace

C#:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;

/// <summary> 
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class ObservableRangeCollection<T> : ObservableCollection<T>
{
    /// <summary> 
    /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
    /// </summary> 
    public void AddRange(IEnumerable<T> collection)
    {
        if (collection == null) throw new ArgumentNullException("collection");

        foreach (var i in collection) Items.Add(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    /// <summary> 
    /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). 
    /// </summary> 
    public void RemoveRange(IEnumerable<T> collection)
    {
        if (collection == null) throw new ArgumentNullException("collection");

        foreach (var i in collection) Items.Remove(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    /// <summary> 
    /// Clears the current collection and replaces it with the specified item. 
    /// </summary> 
    public void Replace(T item)
    {
        ReplaceRange(new T[] { item });
    }

    /// <summary> 
    /// Clears the current collection and replaces it with the specified collection. 
    /// </summary> 
    public void ReplaceRange(IEnumerable<T> collection)
    {
        if (collection == null) throw new ArgumentNullException("collection");

        Items.Clear();
        foreach (var i in collection) Items.Add(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    /// <summary> 
    /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
    /// </summary> 
    public ObservableRangeCollection()
        : base() { }

    /// <summary> 
    /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
    /// </summary> 
    /// <param name="collection">collection: The collection from which the elements are copied.</param> 
    /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
    public ObservableRangeCollection(IEnumerable<T> collection)
        : base(collection) { }
}

更新 - 可观察范围集合,带有集合更改通知

Imports System.Collections.Specialized
Imports System.ComponentModel
Imports System.Collections.ObjectModel

Public Class ObservableRangeCollection(Of T) : Inherits ObservableCollection(Of T) : Implements INotifyCollectionChanging(Of T)
    ''' <summary>
    ''' Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        MyBase.New()
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection.
    ''' </summary>
    ''' <param name="collection">collection: The collection from which the elements are copied.</param>
    ''' <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception>
    Public Sub New(ByVal collection As IEnumerable(Of T))
        MyBase.New(collection)
    End Sub

    ''' <summary>
    ''' Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
    ''' </summary>
    Public Sub AddRange(ByVal collection As IEnumerable(Of T))
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Add, collection)
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        Dim index = Items.Count - 1
        For Each i In collection
            Items.Add(i)
        Next

        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection, index))
    End Sub


    ''' <summary>
    ''' Inserts the collection at specified index.
    ''' </summary>
    Public Sub InsertRange(ByVal index As Integer, ByVal Collection As IEnumerable(Of T))
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Add, Collection)
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        For Each i In Collection
            Items.Insert(index, i)
        Next

        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
    End Sub


    ''' <summary>
    ''' Removes the first occurence of each item in the specified collection from ObservableCollection(Of T).
    ''' </summary>
    Public Sub RemoveRange(ByVal collection As IEnumerable(Of T))
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Remove, collection)
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        For Each i In collection
            Items.Remove(i)
        Next

        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
    End Sub



    ''' <summary>
    ''' Clears the current collection and replaces it with the specified item.
    ''' </summary>
    Public Sub Replace(ByVal item As T)
        ReplaceRange(New T() {item})
    End Sub

    ''' <summary>
    ''' Clears the current collection and replaces it with the specified collection.
    ''' </summary>
    Public Sub ReplaceRange(ByVal collection As IEnumerable(Of T))
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Replace, Items)
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        Items.Clear()
        For Each i In collection
            Items.Add(i)
        Next
        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
    End Sub

    Protected Overrides Sub ClearItems()
        Dim e As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Reset, Items)
        OnCollectionChanging(e)

        If e.Cancel Then Exit Sub

        MyBase.ClearItems()
    End Sub

    Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As T)
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Add, item)
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        MyBase.InsertItem(index, item)
    End Sub

    Protected Overrides Sub MoveItem(ByVal oldIndex As Integer, ByVal newIndex As Integer)
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)()
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        MyBase.MoveItem(oldIndex, newIndex)
    End Sub

    Protected Overrides Sub RemoveItem(ByVal index As Integer)
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Remove, Items(index))
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        MyBase.RemoveItem(index)
    End Sub

    Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As T)
        Dim ce As New NotifyCollectionChangingEventArgs(Of T)(NotifyCollectionChangedAction.Replace, Items(index))
        OnCollectionChanging(ce)
        If ce.Cancel Then Exit Sub

        MyBase.SetItem(index, item)
    End Sub

    Protected Overrides Sub OnCollectionChanged(ByVal e As Specialized.NotifyCollectionChangedEventArgs)
        If e.NewItems IsNot Nothing Then
            For Each i As T In e.NewItems
                If TypeOf i Is INotifyPropertyChanged Then AddHandler DirectCast(i, INotifyPropertyChanged).PropertyChanged, AddressOf Item_PropertyChanged
            Next
        End If
        MyBase.OnCollectionChanged(e)
    End Sub

    Private Sub Item_PropertyChanged(ByVal sender As T, ByVal e As ComponentModel.PropertyChangedEventArgs)
        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, sender, IndexOf(sender)))
    End Sub

    Public Event CollectionChanging(ByVal sender As Object, ByVal e As NotifyCollectionChangingEventArgs(Of T)) Implements INotifyCollectionChanging(Of T).CollectionChanging
    Protected Overridable Sub OnCollectionChanging(ByVal e As NotifyCollectionChangingEventArgs(Of T))
        RaiseEvent CollectionChanging(Me, e)
    End Sub
End Class


Public Interface INotifyCollectionChanging(Of T)
    Event CollectionChanging(ByVal sender As Object, ByVal e As NotifyCollectionChangingEventArgs(Of T))
End Interface

Public Class NotifyCollectionChangingEventArgs(Of T) : Inherits CancelEventArgs

    Public Sub New()
        m_Action = NotifyCollectionChangedAction.Move
        m_Items = New T() {}
    End Sub

    Public Sub New(ByVal action As NotifyCollectionChangedAction, ByVal item As T)
        m_Action = action
        m_Items = New T() {item}
    End Sub

    Public Sub New(ByVal action As NotifyCollectionChangedAction, ByVal items As IEnumerable(Of T))
        m_Action = action
        m_Items = items
    End Sub

    Private m_Action As NotifyCollectionChangedAction
    Public ReadOnly Property Action() As NotifyCollectionChangedAction
        Get
            Return m_Action
        End Get
    End Property

    Private m_Items As IList
    Public ReadOnly Property Items() As IEnumerable(Of T)
        Get
            Return m_Items
        End Get
    End Property
End Class
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ObservableCollection 不支持 AddRange 方法,因此我会收到添加的每个项目的通知,除了 INotifyCollectionChanging 之外? 的相关文章

随机推荐

  • Android:将sqlite数据库内容加载到webview

    我有一个sqlite我有一个要加载的内容的数据库webview 如我所愿从数据库中选择并在网页视图中显示 有什么办法可以做到吗 public class TataworatYawmeeh extends Activity WebView w
  • 共享内存与 Go 通道通信

    Go 的口号之一是不要通过共享内存进行通信 相反 通过通信来共享内存 http golang org doc effective go html concurrency 我想知道 Go 是否允许在同一台机器上运行的两个不同的 Go 编译的二
  • Jupyter python3笔记本无法识别pandas

    我正在使用 Jupyter 笔记本并选择了 Python 3 在单元格的第一行我输入 import pandas as pd 我从笔记本中得到的错误是 ImportError 没有名为 pandas 的模块 如何将pandas安装到jupy
  • 使用 matplotlib 设置网络中的动态节点形状

    第一次在这里发帖 请大家多多包涵 我正在尝试在 Networkx 中绘制不同类型的字符网络 并希望为每种类型设置不同的节点形状 例如 我希望角色是圆形 生物是三角形等 我已经尝试了几个小时来解决这个问题并进行了广泛的搜索 但我还没有找到一种
  • 如何验证自签名认证

    我会清楚地向您提供我的问题 以便您可以回答我 我有一个使用 SslStream 保护的客户端 服务器 套接字 连接 据我所知 使用 ssl 确保我的客户端只会连接到我的服务器 为此 我必须向客户端添加一个函数来验证服务器认证并确保服务器是真
  • ClassNotFoundException,在运行 Hadoop 示例作业时

    我已经开始做一些关于 hadoop 的事情了 它已设置并正常运行 现在我正在做一个单节点 独立集群 我正在尝试运行示例作业 如上面提到的http hadoop apache org common docs r0 18 3 mapred tu
  • 干预图片圆角上传

    我正在尝试将文件上传为圆圈 但无法使其工作 我看过一些有关对图像应用蒙版的主题 但是当我应用蒙版时 它需要很长时间并且服务器会关闭请求 我正在使用Intervention ImageLaravel 的库 我的代码如下 identifier
  • ANR keyDispatchingTimedOut 错误

    当我尝试使用 DOM 解析 RSS 时 我在我的应用程序中遇到了强制向下错误 但是 这并不总是强制向下问题 这是 logcat ANR keyDispatchingTimedOut DALVIK THREADS main prio 5 ti
  • iOS 中接收到 APNS 时打开视图控制器

    嘿 我是 iPhone 新手 我一直在尝试使用 Apple 推送通知 基本上 我想要做的是 当用户单击收到的推送通知消息时 我需要打开一个特定的视图控制器 我已将带有关键参数 type 的自定义数据添加到我的负载 JSON 中 因此代表通知
  • Dagger2 继承的子组件多重绑定

    希望经过日复一日的研究这个非常感兴趣的主题 继承的子组件 后在这里找到一些帮助multibindings你可以在这里找到继承的子组件多重绑定 https dagger dev multibindings这是该页面的最后一个主题 根据官方文档
  • Windows通用应用程序无需网络即可连续听写

    按照此处提供的示例 https github com Microsoft Windows universal samples https github com Microsoft Windows universal samples很好地概述
  • 使用钢筋时的常见测试覆盖报告

    我有一个使用 Rebar 的 Erlang 应用程序 并且有使用 Common Test 编写的测试 我想查看这些测试的测试覆盖率报告 因此我在我的rebar config file cover enabled true 然而 通用测试报告
  • 如何为 pytorch 图层指定名称?

    下列的上一个问题 https stackoverflow com questions 66137298 how to detect source of under fitting and vanishing gradients in pyt
  • 向 SQL Server 插入数据不起作用,但没有错误消息显示

    我正在使用 asp net 4 5 和 SQL Server 2008 Express 我想将表单的数据插入到我的数据库中 连接字符串正常并且可以在另一个页面中工作 但在此页面中 插入按钮似乎只是刷新页面并且没有发生插入 代码 protec
  • 什么准则适合确定何时将类成员实现为属性还是方法?

    The 已开始出现在 赞助者 区域中的信息似乎表明该属性仅适用于逻辑数据成员 请参阅文档的第 34 35 页 在以下情况下 方法被认为是适当的 该操作是一个转换 例如Object ToString 该操作的成本足够高 您希望告知用户他们应该
  • 强制 rvest 识别表(html_tag(x) == "table" 不是 TRUE)

    我似乎永远无法得到html table 上班 这是一个完美的例子 试图刮6场比赛 桌子 library rvest hockey lt html http www hockey reference com boxscores 2015 3
  • 汇编扩展寄存器不工作

    我对 Assembly 和 TASM 相当陌生 我有以下问题 我想使用寄存器的扩展版本 特别是 EBX 通过使用下面的代码 但没有 386 指令 它不起作用 说 未定义的符号 EBX 但有了它 它无法识别 INT 21h 指令 据我了解 该
  • 如何确定用户在浏览器中的区域设置?

    我有一个本地化为十几种语言的网站 Flash 我想根据用户的浏览器设置自动定义默认值 以尽量减少访问内容的步骤 仅供参考 由于代理限制 我无法使用服务器脚本 因此我想 JavaScript 或 ActionScript 适合解决该问题 问题
  • 与多个协作者进行单元测试

    今天我遇到了一个非常困难的TDD问题 我需要通过 HTTP POST 与服务器交互 我找到了 Apache Commons HttpClient 它可以满足我的需要 然而 我最终得到了一堆来自 Apache Commons 的协作对象 pu
  • ObservableCollection 不支持 AddRange 方法,因此我会收到添加的每个项目的通知,除了 INotifyCollectionChanging 之外?

    我希望能够添加一个范围并获得整个批量的更新 我还希望能够在操作完成之前取消该操作 即除了 更改 之外的集合更改 相关问题哪个 Net 集合可用于一次添加多个对象并获得通知 https stackoverflow com questions