WPF の中核となる技術的利点の 1 つはデータ バインディングです。データ バインディングは、データ操作を通じてインターフェイスを更新できます。
データ バインディングに最もよく使用される 2 つのクラスは、ObservableCollection8742468051c85b06f0a0af9e3e506b5c と Dictionary6e081e925c6a2fa99508161fe1ff33ed です。
ObservableCollection は動的データ コレクションを表します。このコレクションは、アイテムが追加されたとき、アイテムが削除されたとき、またはリスト全体が更新されたときに通知を提供します。コレクション データを更新することでインターフェイスの表示を更新できます。
Dictionary 辞書クラスは検索やデータ操作のパフォーマンスが非常に悪いため、一部の設定項目のコレクションはこれを使用して保存されます。
そこで、ObservableCollectionとDictionaryを組み合わせたクラスがないか皆で考え、ObservableDictionaryクラスが形成されました。
ObservableDictionary クラスのバージョンはインターネット上にたくさんあります。私の知る限り、最も古くて古典的なものは、Dr.WPF の辞書への ItemsControl です (私が間違っている場合)。 、私は無知です))。
今日提供するバージョンは、インターネット上の他のバージョンや Dr.WPF のバージョンも参照しています。
Dr.WPF での定義は次のとおりです:
public class ObservableDictionary <TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, INotifyCollectionChanged, INotifyPropertyChanged
よく見ると、ここで継承されたインターフェイスは、Dictionaryb6842da76bed01162354d37c4f2d3464 によって継承されたインターフェイスとほとんど同じであることがわかりますが、次の点が異なります。 INotifyCollectionChanged、INotifyPropertyChanged
したがって、今日私が提供するバージョンは、Dictionary
テストしましたが、バグはなく、パフォーマンスは優れています。コードは以下のとおりです:
public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged { public ObservableDictionary() : base() { } private int _index; public event NotifyCollectionChangedEventHandler CollectionChanged; public event PropertyChangedEventHandler PropertyChanged; public new KeyCollection Keys { get { return base.Keys; } } public new ValueCollection Values { get { return base.Values; } } public new int Count { get { return base.Count; } } public new TValue this[TKey key] { get { return this.GetValue(key); } set { this.SetValue(key, value); } } public TValue this[int index] { get { return this.GetIndexValue(index); } set { this.SetIndexValue(index, value); } } public new void Add(TKey key, TValue value) { base.Add(key, value); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this.FindPair(key), _index)); OnPropertyChanged("Keys"); OnPropertyChanged("Values"); OnPropertyChanged("Count"); } public new void Clear() { base.Clear(); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); OnPropertyChanged("Keys"); OnPropertyChanged("Values"); OnPropertyChanged("Count"); } public new bool Remove(TKey key) { var pair = this.FindPair(key); if (base.Remove(key)) { this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, pair, _index)); OnPropertyChanged("Keys"); OnPropertyChanged("Values"); OnPropertyChanged("Count"); return true; } return false; } protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (this.CollectionChanged != null) { this.CollectionChanged(this, e); } } protected void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #region private方法 private TValue GetIndexValue(int index) { for (int i = 0; i < this.Count; i++) { if (i == index) { var pair = this.ElementAt(i); return pair.Value; } } return default(TValue); } private void SetIndexValue(int index, TValue value) { try { var pair = this.ElementAtOrDefault(index); SetValue(pair.Key, value); } catch (Exception) { } } private TValue GetValue(TKey key) { if (base.ContainsKey(key)) { return base[key]; } else { return default(TValue); } } private void SetValue(TKey key, TValue value) { if (base.ContainsKey(key)) { var pair = this.FindPair(key); int index = _index; base[key] = value; var newpair = this.FindPair(key); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newpair, pair, index)); OnPropertyChanged("Values"); OnPropertyChanged("Item[]"); } else { this.Add(key, value); } } private KeyValuePair<TKey, TValue> FindPair(TKey key) { _index = 0; foreach (var item in this) { if (item.Key.Equals(key)) { return item; } _index++; } return default(KeyValuePair<TKey, TValue>); } private int IndexOf(TKey key) { int index = 0; foreach (var item in this) { if (item.Key.Equals(key)) { return index; } index++; } return -1; } #endregion }
拡張に関しては、より技術的でスケーラブルな Dr.WPF バージョンを使用して変更できます。 !
以上がWPF データ バインディングのコア テクノロジの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。