gpt4 book ai didi

c# - 将列表(ObservableCollection)复制到另一个

转载 作者:太空宇宙 更新时间:2023-11-03 13:18:57 25 4
gpt4 key购买 nike

我有一个列表,其中有很多实时更新,所以我想每隔 1 秒将这个 Observable 集合中的所有更改复制到另一个集合中。我该怎么做?

我尝试的是:

var temp = CalculateMyObservableCollection();
var temp2 = (INotifyCollectionChanged) temp.SourceCollection;

Observable.FromEventPattern<CollectionChangeEventArgs>(temp2, "CollectionChanged")
.Throttle(new TimeSpan(1000))
.Select(i => i.Sender)
.Subscribe(UpdateItems);

private void UpdateItems(object obj)
{
if (obj is MyClass)
Items.AddNewItem(obj as MyClass);
}

这似乎是完全错误的!!

最佳答案

我已经实现了一个节流的可观察集合,也许可以解决您的问题。

INotifyCollectionChanged 接口(interface)可以提供详细的更改通知,描述确切的集合更改,其中更改操作由 Action 指示事件参数的属性。但是,当更改受到限制时,您将失去跟踪有关更改的详细信息的能力,因为无法表达添加和删除元素的复杂更改。相反 Reset必须使用操作来表示集合的内容发生了巨大变化

class ThrottledObservableCollection<T> : IReadOnlyCollection<T>, INotifyCollectionChanged, INotifyPropertyChanged, IDisposable {

List<T> _list;

IDisposable _subscription;

public ThrottledObservableCollection(ObservableCollection<T> source, TimeSpan throttleInterval) {
if (source == null)
throw new ArgumentNullException("source");
_list = new List<T>(source);
_subscription = Observable
.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
handler => source.CollectionChanged += handler,
handler => source.CollectionChanged -= handler
)
.Throttle(throttleInterval)
.Subscribe(HandleSourceChanged);
}

void HandleSourceChanged(EventPattern<NotifyCollectionChangedEventArgs> eventPattern) {
var source = (IEnumerable<T>) eventPattern.Sender;
_list = new List<T>(source);
OnPropertyChanged("Count");
OnCollectionChanged();
}

public Int32 Count { get { return _list.Count; } }

public IEnumerator<T> GetEnumerator() {
return _list.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(String propertyName) {
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}

public event NotifyCollectionChangedEventHandler CollectionChanged;

protected void OnCollectionChanged() {
var handler = CollectionChanged;
if (handler != null)
handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}

public void Dispose() {
Dispose(true);
}

protected void Dispose(Boolean disposing) {
_subscription.Dispose();
}

}

请注意,此类不是线程安全的,如果多个线程同时更改源集合,您可能需要一些额外的保护。

这里是如何使用集合:

var observableCollection = new ObservableCollection<Item>();
var throttledObservableCollection = new ThrottledObservableCollection<Item>(
observableCollection,
TimeSpan.FromSeconds(1)
);
throttledObservableCollection.CollectionChanged += ...

// 2 CollectionChanged events will fire from this code.
observableCollection.Add(new Item());
observableCollection.Add(new Item());
Thread.Sleep(TimeSpan.FromSeconds(1.1));
observableCollection.Add(new Item());

关于c# - 将列表(ObservableCollection)复制到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25037744/

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