J'essaie d'utiliser la suivi de la mise en œuvre de l'observation de l'observation: Observexdictionner (C #) .
Lorsque j'utilise le code suivant en liant le dictionnaire à un Datagramrid: P>
private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem) { OnPropertyChanged(); if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem)); }
5 Réponses :
Structure de données similaire, pour se lier à la collection type de dictionnaire P>
http: / /drwpf.com/blog/2007/09/16/CAN-IMTIND-MY-ITEMSCONTROL-A-A-Dictionary/ P>
Il fournit une nouvelle structure de données observée et incendie Propertyhanged en cas de changement au dictionnaire sous-jacent. p>
Voici ce que j'ai fait à la fin:
[Serializable] public class ObservableKeyValuePair<TKey,TValue>:INotifyPropertyChanged { #region properties private TKey key; private TValue value; public TKey Key { get { return key; } set { key = value; OnPropertyChanged("Key"); } } public TValue Value { get { return value; } set { this.value = value; OnPropertyChanged("Value"); } } #endregion #region INotifyPropertyChanged Members [field:NonSerialized] public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(name)); } #endregion } [Serializable] public class ObservableDictionary<TKey,TValue>:ObservableCollection<ObservableKeyValuePair<TKey,TValue>>, IDictionary<TKey,TValue> { #region IDictionary<TKey,TValue> Members public void Add(TKey key, TValue value) { if (ContainsKey(key)) { throw new ArgumentException("The dictionary already contains the key"); } base.Add(new ObservableKeyValuePair<TKey, TValue>() {Key = key, Value = value}); } public bool ContainsKey(TKey key) { //var m=base.FirstOrDefault((i) => i.Key == key); var r = ThisAsCollection().FirstOrDefault((i) => Equals(key, i.Key)); return !Equals(default(ObservableKeyValuePair<TKey, TValue>), r); } bool Equals<TKey>(TKey a, TKey b) { return EqualityComparer<TKey>.Default.Equals(a, b); } private ObservableCollection<ObservableKeyValuePair<TKey, TValue>> ThisAsCollection() { return this; } public ICollection<TKey> Keys { get { return (from i in ThisAsCollection() select i.Key).ToList(); } } public bool Remove(TKey key) { var remove = ThisAsCollection().Where(pair => Equals(key, pair.Key)).ToList(); foreach (var pair in remove) { ThisAsCollection().Remove(pair); } return remove.Count > 0; } public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); var r = GetKvpByTheKey(key); if (!Equals(r, default(ObservableKeyValuePair<TKey, TValue>))) { return false; } value = r.Value; return true; } private ObservableKeyValuePair<TKey, TValue> GetKvpByTheKey(TKey key) { return ThisAsCollection().FirstOrDefault((i) => i.Key.Equals(key)); } public ICollection<TValue> Values { get { return (from i in ThisAsCollection() select i.Value).ToList(); } } public TValue this[TKey key] { get { TValue result; if (!TryGetValue(key,out result)) { throw new ArgumentException("Key not found"); } return result; } set { if (ContainsKey(key)) { GetKvpByTheKey(key).Value = value; } else { Add(key, value); } } } #endregion #region ICollection<KeyValuePair<TKey,TValue>> Members public void Add(KeyValuePair<TKey, TValue> item) { Add(item.Key, item.Value); } public bool Contains(KeyValuePair<TKey, TValue> item) { var r = GetKvpByTheKey(item.Key); if (Equals(r, default(ObservableKeyValuePair<TKey, TValue>))) { return false; } return Equals(r.Value, item.Value); } public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { throw new NotImplementedException(); } public bool IsReadOnly { get { return false; } } public bool Remove(KeyValuePair<TKey, TValue> item) { var r = GetKvpByTheKey(item.Key); if (Equals(r, default(ObservableKeyValuePair<TKey, TValue>))) { return false; } if (!Equals(r.Value,item.Value)) { return false ; } return ThisAsCollection().Remove(r); } #endregion #region IEnumerable<KeyValuePair<TKey,TValue>> Members public new IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return (from i in ThisAsCollection() select new KeyValuePair<TKey, TValue>(i.Key, i.Value)).ToList().GetEnumerator(); } #endregion }
IMO, ce n'est pas bon (pour les grandes données), car le but principal du dictionnaire est de ne pas stocker, mais de récupérer rapidement la récupération à l'aide de techniques de hachage. Ce lien a > A véritable observateur avec récupération rapide. (comme enveloppe observictionnaires sur le dictionnaire)
Bon travail! Dans trygetvalue code>, l'instruction IF doit être
si (égale (R, défaut (ObservableKeyValuePair
Même j'utilise l'observateur de Github, j'ai également fait face à cette exception. J'avais déclaré la variable du dictionnaire au niveau de la classe plus tard, j'ai essayé de créer une nouvelle instance dans la méthode où il a été accédé.
OldCode qui a donné une exception: P>
public void MethodName() { ObservableDictionary<string, string> _localVariableDictionary = new ObservableDictionary<string, string>(); }
Observexcédictionnement a été ajouté à la technologie .NET à la version 4.5: - p>
https: //zamjad.wordpress. COM / 2012/10/12 / Observexdictionn-in-Net-4-5 / P>
Voici un lien vers le dernier code source: - p>
Voyez-vous qu'il est interne code>?
J'ai fini par écrire une classe pour contenir la paire de valeur de clé et utiliser une collection de cette classe. J'utilise Caliburn Micro, où vient la liablecolection, mais une observablecollection devrait fonctionner de la même manière. J'utilise le motif MVVM.
la vue Mododel p> le keyvaluepair personnalisé p> et dans la vue P> <ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding Key, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="1"
Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
gist.github.com/kzu/cfe3cb6e4fe3efea6d24 Ceci semble très bon