将整个ObservableCollection替换为另一个ObservableCollection

public class Alpha { public ObservableCollection Items { get; set; } public Alpha() { Items = new ObservableCollection(); } public void DoSomething() { Items = GetNewItems(); // whenever I do this, Items gets a new referene, // so every WPF binding (eg datagrids) are broken } public ObservableCollection GetNewItems() { var ret = new ObservableCollection(); // some logic for getting some items from somewhere, and populating ret return ret; } } 

如何在不使用GetNewItems()的返回值的情况下替换Items的整个内容:

  1. 打破绑定。

  2. 必须遍历项目并将它们逐个复制到另一个集合中?

你有一些选择:

  1. 实现INotifyPropertyChanged,以便您可以通知UI项的值已更改。 这不利用在ObservableCollection上实现INotifyCollectionChanged的事实。 它会起作用,但它首先违背了使用ObservableCollection的目的。 不建议这样做,但它有效。
  2. 使用ObservableCollection的Add / Remove / Modify / Update方法与Dispatcher一起修改它。
    • 注意:如果没有Dispatcher,您将收到NotSupportedException,因为CollectionViews不支持从与Dispatcher线程不同的线程更改其SourceCollection
  3. 使用ObservableCollection的Add / Remove / Modify / Update方法将其与BindingOperations.EnableCollectionSynchronization一起修改。 推荐的
    • 注意:这仅适用于.NET 4.5。
    • 这是在避免使用NotSupportedException时使用Dispatcher的替代方法。

关于你的问题,数字2和3转换为清除现有项目(Clear()),然后添加(Add())通过任何方法返回的项目 – 请参阅#3的示例。 它们的关键是清除和所有添加必须使用Dispatcher(2)或通过调用BindingOperations.EnableCollectionSynchronization 。 祝好运!

参考: Reed Copsey答案 – StackOverflow

您还可以创建自己的类来扩展ObservableCollection,这是一个通知排序的示例:

https://github.com/jamesmontemagno/mvvm-helpers/blob/master/MvvmHelpers/ObservableRangeCollection.cs

我正在使用上面更简单的实现(我没有比较通知方面):

 using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Runtime.CompilerServices; using BaseLibrary.Properties; namespace BaseLibrary { ///  /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. ///  ///  public class ObservableCollectionEx : ObservableCollection { //INotifyPropertyChanged interited from ObservableCollection #region INotifyPropertyChanged protected override event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] public void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion INotifyPropertyChanged ///  /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). ///  public void AddRange(IEnumerable collection) { if (collection == null) throw new ArgumentNullException(nameof(collection)); foreach (var i in collection) Items.Add(i); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } ///  /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). ///  public void RemoveRange(IEnumerable collection) { if (collection == null) throw new ArgumentNullException(nameof(collection)); foreach (var i in collection) Items.Remove(i); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } ///  /// Clears the current collection and replaces it with the specified item. ///  public void Replace(T item) { Replace(new T[] { item }); } ///  /// Replaces all elements in existing collection with specified collection of the ObservableCollection(Of T). ///  public void Replace(IEnumerable collection) { if (collection == null) throw new ArgumentNullException(nameof(collection)); Items.Clear(); foreach (var i in collection) Items.Add(i); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } ///  /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. ///  public ObservableCollectionEx() : base() { } ///  /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. ///  /// collection: The collection from which the elements are copied. /// The collection parameter cannot be null. public ObservableCollectionEx(IEnumerable collection) : base(collection) { } } 

}

ObservableCollection实现了INotifyCollectionChanged,它将在添加或删除项时更新绑定。 这里需要的只是清除要触发的CollectionChanged事件的列表。

 public void GetNewItems() { Items.Clear(); // some logic for getting some items from somewhere, and populating ret }