我想創建一個ObservableConcurrentDictionary。此對象將用於多線程應用程序,並且它的數據用於通過控件ItemsSource屬性填充控件。如何創建使用ConcurrentDictionary,INotifyCollectionChanged定製觀察的集合,INotifyPropertyChanged的
這是我想出了實施:
public sealed class ObservableConcurrentDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
{
#region Constructors
public ObservableConcurrentDictionary()
: base()
{
}
public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection)
: base(collection)
{
}
public ObservableConcurrentDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
}
public ObservableConcurrentDictionary(int concurrencyLevel, int capacity)
: base(concurrencyLevel, capacity)
{
}
public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: base(collection, comparer)
{
}
public ObservableConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
: base(concurrencyLevel, capacity, comparer)
{
}
public ObservableConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: base(concurrencyLevel, collection, comparer)
{
}
#endregion
#region Public Methods
public new TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
{
// Stores the value
TValue value;
// If key exists
if (base.ContainsKey(key))
{
// Update value and raise event
value = base.AddOrUpdate(key, addValueFactory, updateValueFactory);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace));
}
// Else if key does not exist
else
{
// Add value and raise event
value = base.AddOrUpdate(key, addValueFactory, updateValueFactory);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
}
// Returns the value
return value;
}
public void Clear()
{
// Clear dictionary
base.Clear();
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public new TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
// Stores the value
TValue value;
// If key exists
if (base.ContainsKey(key))
// Get value
value = base.GetOrAdd(key, valueFactory);
// Else if key does not exist
else
{
// Add value and raise event
value = base.GetOrAdd(key, valueFactory);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
}
// Return value
return value;
}
public new TValue GetOrAdd(TKey key, TValue value)
{
// If key exists
if (base.ContainsKey(key))
// Get value
base.GetOrAdd(key, value);
// Else if key does not exist
else
{
// Add value and raise event
base.GetOrAdd(key, value);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
}
// Return value
return value;
}
public new bool TryAdd(TKey key, TValue value)
{
// Stores tryAdd
bool tryAdd;
// If added
if (tryAdd = base.TryAdd(key, value))
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
// Return tryAdd
return tryAdd;
}
public new bool TryRemove(TKey key, out TValue value)
{
// Stores tryRemove
bool tryRemove;
// If removed
if (tryRemove = base.TryRemove(key, out value))
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
// Return tryAdd
return tryRemove;
}
public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
{
// Stores tryUpdate
bool tryUpdate;
// If updated
if (tryUpdate = base.TryUpdate(key, newValue, comparisonValue))
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace));
// Return tryUpdate
return tryUpdate;
}
#endregion
#region Private Methods
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
CollectionChanged(this, e);
}
#endregion
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
不幸的是,解決方案不會像預期的那樣 - 事實上,它並沒有在所有的工作。關於我在做什麼錯誤或做出更好的解決方案的任何想法存在?
請注意,我不能使用的ObservableCollection,因此,我必須寫我自己的觀察的集合。
編輯: 工作版本如下。希望這可以幫助有類似問題的其他人。
public sealed class ObservableConcurrentDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
{
public ObservableConcurrentDictionary()
: base()
{
}
public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection)
: base(collection)
{
}
public ObservableConcurrentDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
}
public ObservableConcurrentDictionary(int concurrencyLevel, int capacity)
: base(concurrencyLevel, capacity)
{
}
public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: base(collection, comparer)
{
}
public ObservableConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
: base(concurrencyLevel, capacity, comparer)
{
}
public ObservableConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: base(concurrencyLevel, collection, comparer)
{
}
public new TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
{
// Stores the value
TValue value;
// If key exists
if (base.ContainsKey(key))
{
// Update value and raise event
value = base.AddOrUpdate(key, addValueFactory, updateValueFactory);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value));
}
// Else if key does not exist
else
{
// Add value and raise event
value = base.AddOrUpdate(key, addValueFactory, updateValueFactory);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value));
}
// Returns the value
return value;
}
public new void Clear()
{
// Clear dictionary
base.Clear();
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public new TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
// Stores the value
TValue value;
// If key exists
if (base.ContainsKey(key))
// Get value
value = base.GetOrAdd(key, valueFactory);
// Else if key does not exist
else
{
// Add value and raise event
value = base.GetOrAdd(key, valueFactory);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value));
}
// Return value
return value;
}
public new TValue GetOrAdd(TKey key, TValue value)
{
// If key exists
if (base.ContainsKey(key))
// Get value
base.GetOrAdd(key, value);
// Else if key does not exist
else
{
// Add value and raise event
base.GetOrAdd(key, value);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value));
}
// Return value
return value;
}
public new bool TryAdd(TKey key, TValue value)
{
// Stores tryAdd
bool tryAdd;
// If added
if (tryAdd = base.TryAdd(key, value))
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value));
// Return tryAdd
return tryAdd;
}
public new bool TryRemove(TKey key, out TValue value)
{
// Stores tryRemove
bool tryRemove;
// If removed
if (tryRemove = base.TryRemove(key, out value))
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, value));
// Return tryAdd
return tryRemove;
}
public new bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
{
// Stores tryUpdate
bool tryUpdate;
// If updated
if (tryUpdate = base.TryUpdate(key, newValue, comparisonValue))
// Raise event
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newValue));
// Return tryUpdate
return tryUpdate;
}
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
CollectionChanged(this, e);
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event PropertyChangedEventHandler PropertyChanged;
}
「它根本不起作用」 - 是無效的問題描述。 請告訴我們您收到了哪些錯誤,您使用哪些代碼來測試它以及您無法使用ObservableCollection的原因。 – Euphoric 2010-10-14 11:37:02