WPF字典集合类ObservableDictionary
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版本来修改,那个更加有技术含量和可扩展性更强!
WPF字典集合类ObservableDictionary的更多相关文章
- python day4 元组/字典/集合类知识点补充
目录 python day4 元组/字典/集合类知识点补充 1. 元组tuple知识点补充 2. 字典dict的知识点补充 3. 基本数据类型set 4. 三元运算,又叫三目运算 5. 深复制浅复制 ...
- C# - 集合类 - 集合接口
本篇将介绍关于集合的接口 这些接口定义了所有与集合有关的类的框架 IEnumerable接口 ns:System.Collections 此接口定义了对集合遍历的方法 一般表示元素序列或集合的类都实现 ...
- C# - 常用接口
常用接口 用于比较接口 IComparable<T> 接口内部定义了用于比较两个对象大小的CompareTo(T t)方法,>参数时返回1,=参数时返回0,<参数时返回-1.集 ...
- 泛型List、HashTable
从最开始接触的数组,到非泛型集合类(ArrayList.HashTable.Queue.Stack).泛型集合类(List<T>.Dictionary<T>.Queue< ...
- 【DG】Oracle_Data_Guard官方直译
[DG]Oracle Data Guard官方直译 1 Oracle Data Guard 介绍 Oracle Data Guard概念和管理10g版本2 Oracle Data Guard ...
- DVWA实验之Brute Force(暴力破解)- Low
DVWA实验之Brute Force-暴力破解- Low 这里开始DVWA的相关实验~ 有关DVWA环境搭建的教程请参考: https://www.cnblogs.com/0yst3r-2 ...
- Oracle错误览表
Oracle 错误总结及问题解决 ORA 本文转自:https://www.cnblogs.com/zhangwei595806165/p/4972016.html 作者@承影剑 ORA-0 ...
- [原创]WPF资源Binding自定义集合类。
简单介绍一下Wpf资源字典: 每个WPF界面元素都有一个名为Resource的属性,这个属性继承至FrameworkElement类,其类型为ResourceDictionary.ResourceDi ...
- [WPF]资源字典——程序集之间的资源共享 简单换皮肤
直接上代码,已便已后自己查况阅,新手也可以看! 1.新建一个资料类和一个WPF工程 2.APP.XAML应该资源字典,注意应Source格式,前面一定要有“/” <ResourceDiction ...
随机推荐
- AD转换
一.AD转换的概念 AD转换的功能是把模拟量电压转换为数字量电压.DA转换的功能正好相反,就是讲数字量转换位模拟量. 二.芯片PCF8591介绍 PCF8591是一个单片集成.单独供电.低功耗.8- ...
- thinkphp5z
解决验证类下找不到指定的类,就在D:\phpStudy\www\vuethink\php\application\admin\validate\service.php,缺少验证类文件service.p ...
- Thinkphp5.0+Vue2.0前后端分离框架Vuethink
VueThink是一套基于Vue全家桶(Vue2.x + Vue-router2.x + Vuex)+ Thinkphp的前后端分离框架. 脚手架构建也可以通过vue官方的vue-cli脚手架工具构建 ...
- dedecms系统后台登陆提示用户名密码不存在
dedecms最近被曝有非常多的安全漏洞,最近有些用户反应后台管理员账号密码没有修改但无法正常登陆,提示用户名不存在,经研究发现是程序漏洞管理员被直接篡改,解决方案如下. 工具/原料 dedecms ...
- 百万级别QPS轻量级PHP框架Steeze介绍
系统简介 Steeze是一个优雅.简洁而又高效的PHP开源框架,在整合了知名框架ThinkPHP和Laravel优点的同时,重写了底层架构,增强了功能实现. 支持swoole模型运行,支持容器.模 ...
- cobol
过程部的语句一般从B区开始书写. ACCEPT A,B (x) DISPLAY T1,T2.(O)显示在一行上 DISPLAY T1 DISPLAY T2 (O)显示在两行上 read ...
- mybatis实战教程三:多对多关联
MyBatis3.0 添加了association和collection标签专门用于对多个相关实体类数据进行级联查询,但仍不支持多个相关实体类数据的级联保存和级联删除操作 一.创建student.te ...
- ImmutableMap
不可变集合,为什么使用它呢?线程安全\更有效的利用内存\可作为常量 ImmutableMap.<String, Object> builder().put("yananList& ...
- Java并发编程的艺术读书笔记(2)-并发编程模型
title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...
- linux 中 ping的回传值
今天在学习鸟哥私房菜的过程中,不明白ping的回传值是怎么设置的,后来网上找的结果了,特此记录一下 1 题目大意是指,ping一个网段的机器,如果可以通,就显示UP,如果不通就显示Down,其中一 ...