WPF最核心的技术优势之一就是数据绑定。数据绑定,可以通过对数据的操作来更新界面。

数据绑定最经常用到的是ObservableCollection<T> 和 Dictionary<T, T> 这两个类。

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

大家细心点就会发现,这里继承的接口和Dictionary<TKey, TValue>所继承的大部分相同,只是多了INotifyCollectionChanged, INotifyPropertyChanged

于是,今天我提供的版本,就直接继承于Dictionary<TKey, TValue>和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版本来修改,那个更加有技术含量和可扩展性更强!

更多相关文章

  1. 让WebAPI 返回JSON格式的数据实例教程
  2. 怎么在EXECL文件中同时导入数据和插入图片?
  3. 关于.net C# Sql数据库SQLHelper类实例代码
  4. 什么是MVVM架构和数据绑定?
  5. 总结EF通用数据层封装类实例详解
  6. 总结MVC中数据验证实例
  7. 详解VS2015自带LocalDB数据库用法实例
  8. ASP.NET MVC中传参并绑定数据的实例教程
  9. ADO.NET实现对SQL Server数据库的操作教程

随机推荐

  1. PHP生成有背景的二维码图片(代码示例)
  2. 分享学好PHP的几个重要心得
  3. Pimple运行流程浅析(PHP容器)
  4. 在PHP中进行会话处理(代码详解)
  5. 利用php实现读取excel中的图片
  6. PHP中经典的四大排序算法
  7. 一文搞懂PHP类和对象、抽象类、接口
  8. 如何通过imagick让PHP生成PSD文件缩略图(
  9. 实例详解php cookie与session会话基本用
  10. PHP 中的 -> 和 :: 的区别