WPF最核心的技术优势之一就是数据绑定。数据绑定,可以通过对数据的操作来更新界面。
数据绑定最经常用到的是ObservableCollection8742468051c85b06f0a0af9e3e506b5c 和 Dictionary6e081e925c6a2fa99508161fe1ff33ed 这两个类。
ObservableCollection表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知,可以通过更新集合数据来更新界面显示。
Dictionary字典类,检索和数据操作性能极性,所以一些配置项的集合都使用它来保存。
因此,大家就想到的,有没有ObservableCollection和Dictionary相结合的类呢,于是就形成的ObservableDictionary类。
网上有很多版本的ObservableDictionary类,据我了解到的,最早且最经典的就是Dr.WPF里面的ItemsControl to a dictionary,其他的版本多数是参考这个来修改的(不对的那就是我孤陋寡闻了)。
今天我提供的这个版本,也是参考了网上的其他版本和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
于是,今天我提供的版本,就直接继承于Dictionaryb6842da76bed01162354d37c4f2d3464和INotifyCollectionChanged, INotifyPropertyChanged。
本人测试过,无BUG,性能也极佳,下面上代码:
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中文网其他相关文章!