gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 03:31:32 37 4
gpt4 key购买 nike

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

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


相关问题 Which .Net collection for adding multiple objects at once and getting notified?

最佳答案

请引用updated and optimized C# 7 version .我不想删除 VB.NET 版本,所以我只是将它发布在一个单独的答案中。

Go to updated version

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

我更新了 VB 版本,从现在开始,它会在更改集合之前引发一个事件,这样你就可以后悔了(在与 DataGridListView 等一起使用时很有用,您可以向用户显示“您确定吗”确认),更新后的 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) { }
}

更新 - 带有集合更改通知的可观察范围集合<​​/h2>
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

关于c# - ObservableCollection 不支持 AddRange 方法,因此除了 INotifyCollectionChanging 之外,我会收到添加的每个项目的通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/670577/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com