我绝对(不)是一个标题党
问题的产生
今日任务————门禁刷卡:
只有当一定数量的人在很短间隔内刷卡才能芝麻开门!一旦到达时间还没有满足人数就会清零。
一开始把「改变容器内容」和「改变显示效果」和「控制大门洞开」分为好几条语句执行,但是这一点都不优雅!
为什么不能在内容发生变化时自动触发事件呢???
想要一个容器,当容器内元素的数量发生变化时就能触发一个事件!
于是乎第一条解决方案
没错那就是 ObservableCollection 类,这个类有个神奇的 CollectionChanged 的事件,一旦内容的数量发生变化就会调用(类似于指针,地址变而不是内容变)
这在容器内只保存「id号码」时相当得好用!
但是我需要同时保存「id号码」和「用户信息」而且这两者不便于组合时就很尴尬了。。。
我一开始想到的是用Tuple,但是写出来代码贼丑而且效率贼低
だから、
咱们来手写一个能监听内容变化的字典吧!
啊,已经写不动了,于是直接代码呈上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
using System;
using System.Collections.Generic;
namespace VehicleSystem.tools { public class ObservableDictionary<TK,TV> { private readonly Dictionary<TK, TV> _dic = new Dictionary<TK, TV>();
public event EventHandler<KeyValuePair<TK, TV>> BeforeAdd;
public event EventHandler<KeyValuePair<TK, TV>> AfterAdd;
public event EventHandler<EventArgs> BeforeClear;
public event EventHandler<EventArgs> AfterClear;
public event EventHandler<EventArgs> OnGetCount;
public event EventHandler<EventArgs> OnGetKeys;
public event EventHandler<EventArgs> OnGetValues;
public event EventHandler<EventArgs> CollectionChanged;
public int Count { get { OnGetCount?.Invoke(this,null); return _dic.Count; } }
public Dictionary<TK, TV>.KeyCollection Keys { get { OnGetKeys?.Invoke(this, null); return _dic.Keys; } }
public Dictionary<TK,TV>.ValueCollection Values { get { OnGetValues?.Invoke(this, null); return _dic.Values; } }
public TV this[TK index] { get { return _dic[index]; } set { _dic[index] = value; CollectionChanged?.Invoke(this, null); } }
public void Add(TK key, TV value) { BeforeAdd?.Invoke(this, new KeyValuePair<TK, TV>(key, value)); _dic.Add(key, value); AfterAdd?.Invoke(this, new KeyValuePair<TK, TV>(key, value)); CollectionChanged?.Invoke(this, null); }
public void Clear() { BeforeClear?.Invoke(this, null); _dic.Clear(); AfterClear?.Invoke(this, null); CollectionChanged?.Invoke(this, null); } } }
|
当然还不是很完美(比如 CollectionChanged 拆解成了四个事件,不过更清晰了有木有!!!)
具体使用的方法如下(节选):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| private readonly ObservableDictionary<string, string> _staffs = new ObservableDictionary<string, string>();
_staffs["key"] _staffs.Values.ToArray()[0]
_staffs.AfterAdd += _staffs_AfterAdd;
private void _staffs_AfterAdd(object sender, KeyValuePair<string, string> e) { e.Key ... e.Value ... }
|
写文章一共花了我50分钟唉,每天都这么写岂不是要累趴。。。
2017年3月27日更新
实现 CollectionChanged 事件