Ich versuche, ein ObservableConcurrentDictionary zu erstellen. Dieses Objekt wird in einer Multithread-Anwendung verwendet und seine Daten werden verwendet, um ein Steuerelement über die ItemsSource-Eigenschaft der Steuerelemente zu füllen.So erstellen Sie eine benutzerdefinierte Observable-Sammlung mit ConcurrentDictionary, INotifyCollectionChanged, INotifyPropertyChanged
Dies ist die Umsetzung i mit gekommen sind:
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
}
Leider ist die Lösung nicht wie vorgesehen - in der Tat ist es nicht bei allen. Irgendwelche Ideen darüber, was ich falsch mache oder bessere Lösungen gebe?
Bitte beachten Sie, dass ich nicht ObservableCollection verwenden kann, daher muss ich meine eigene Observable Sammlung schreiben.
EDIT: Die Arbeitsversion ist unten. Hoffe das hilft jemand anderem mit einem ähnlichen Problem.
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;
}
"es funktioniert überhaupt nicht" - ist keine gültige Problembeschreibung. Bitte teilen Sie uns mit, welche Fehler Sie erhalten, welchen Code Sie zum Testen verwenden und warum Sie ObservableCollection nicht verwenden können. – Euphoric