.NET ObservableDictionary
J'ai écrit cette classe qui implémente(ou tente de le faire!) un dictionnaire avec les notifications:
public partial class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged
{
public ObservableDictionary() : base() { }
public ObservableDictionary(int capacity) : base(capacity) { }
public ObservableDictionary(IEqualityComparer<TKey> comparer) : base(comparer) { }
public ObservableDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { }
public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity, comparer) { }
public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : base(dictionary, comparer) { }
public event NotifyCollectionChangedEventHandler CollectionChanged;
public new TValue this[TKey key]
{
get
{
return base[key];
}
set
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, key, 0));
base[key] = value;
}
}
public new void Add(TKey key, TValue value)
{
base.Add(key, value);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, key, 0));
}
public new bool Remove(TKey key)
{
bool x = base.Remove(key);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, key, 0));
return x;
}
public new void Clear()
{
base.Clear();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(this, e);
}
}
}
Dans une autre classe, j'ai un écouteur pour l' MyObservableDictionary.CollectionChanged
événement:
Le problème, je vais avoir, c'est que l'événement n'a pas le feu. Comment puis-je résoudre ce problème?
- n' "onCollectionChanged" pas de feu, ou de ne "collectionChanged" pas de feu?
- Fournir de l'écouteur d'événement de la classe ..
- En plus de @Tim..'à la question, pouvez-vous montrer le code de la consommation où l'affectation d'un délégué de la méthode pour le gestionnaire d'événement?
- tc.EventHistory.CollectionChanged += new System.Les Collections.Spécialisés.NotifyCollectionChangedEventHandler(EventHistory_CollectionChanged); où tc est le usercontrol contenant le ObservableDictionary(callede EventHistory). Aussi @Tim OnCollectionChanged ne pas le feu
- 10rem.net/blog/2010/03/08/...
Vous devez vous connecter pour publier un commentaire.
Je vous suggère de que vous mettre en œuvre la
IDictionary<TKey, TValue>
au lieu d'hériter deDictionary<TKey, TValue>
. Depuis que vous avez à utilisernew
plutôt queoverride
il est possible que les méthodes sont tout simplement appelée sur la classe de base plutôt que de votre classe. Je serais tenté d'utiliser unDictionary<TKey, TValue>
en interne pour faire le stockage de données.En fait j'ai trouvé ceci:
http://blogs.microsoft.co.il/blogs/shimmy/archive/2010/12/26/observabledictionary-lt-tkey-tvalue-gt-c.aspx
Microsoft ParallelExtensionsExtras fournit cette classe qui n'est pas seulement observable, mais est également simultanées:
Maintenant disponible via Nuget:
https://www.nuget.org/packages/MSFT.ParallelExtensionsExtras/
Noter que certaines fonctionnalités sont maintenant une partie de la plus récente .NET cadres.
Sont les ParallelExtensions "Extras" encore de la valeur?
Microsoft Tour Blog:
https://blogs.msdn.microsoft.com/pfxteam/2010/04/04/a-tour-of-parallelextensionsextras/
La Programmation parallèle un Exemple de Code (code d'origine de Parallel Extensions):
https://code.msdn.microsoft.com/ParExtSamples
IEnumerator IEnumerable.GetEnumerator() { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator(); }
Using the generic type 'System.Collections.Generic.IEnumerator<T>' requires 1 type arguments
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator(); }
.Clear()
parce qu'il n'existent pas. Des idées?Clear
méthode, vous devez jeter le dictionnaire pour laICollection<KeyValuePair<TKey, TValue>>
. Je suggérerais à l'aide d'une suivante de la méthode d'extension:public static ICollection<KeyValuePair<TKey, TValue>> AsCollection<TKey, TValue>(this IDictionary<TKey, TValue> dictionary) { return dictionary; }
Votre solution - Fixe 😉
partial
?J'ai lancé mon propre:
https://www.nuget.org/packages/hellosam.net.collections/
Il utilise AVL arbre, de sorte que les opérations sont en O(log N), où la plupart des implémentations j'ai vu à l'aide de la Liste.indexOf() O(N).
Il peut même observer votre article INotifyPropertyChanged et les convertir en une collection observable de l'événement, de manière à conserver le contrôle DataGrid de tri/groupe de réponse pour le changement.
Comme Ignatio et Matthieu l'a souligné dans cette réponse, seulement de développer le
Reset
collection de notification de changement est incorrect, et pas très utile si l'appelant a besoin de savoir ce qui a réellement changé. Heureusement, il est facilement corrigée. Remarque cette version utiliseSend
au lieu dePost
que Nathan mentionné dans la précédente réponse, parce que WPF est sensible à rendre compte de l'index correct lors de l'enlèvement, et de se tromper rendements cette confusion exception. (Caveat emptor: je ne suis pas encore complètement convaincu que la signalées indice sera totalement fiable si il y a beaucoup de chevauchement des changements, en particulier étant donné que les Dictionnaires doivent être traités comme des non-ordonnée.)J'ai réussi à trouver une solution de contournement
J'ai plus de mettre en œuvre la
INotifyCollectionChanged
interface si.