前言
WPF的一大基础就是Data Binding。在基于MVVM架构的基础上,只有通过实现INotifyPropertyChanged接口的ViewModel才能够用于Data Binding。
要实现INotifyPropertyChanged接口,只需要实现一个事件,event PropertyChangedEventHandler PropertyChange。
作为一个刚接触WPF没多久的人来说,我最不可理解的就是data binding的时候到底谁自动帮我完成了订阅PropertyChanged这个事件?
delegate & event基础知识回顾
先来回顾下C#里delegate和event的基础知识。
我们知道在C#里,event其实就是一种简化的delegate。所谓的简化其实是为了更好地解决订阅和广播的问题。为什么?我们知道在处理订阅时,各个listener之间应该时相互不知道对方的存在的,并且相互间互不影响。delegate和event都通过+=和-=来注册和反注册listener。而delegate还可以通过=进行赋值。这个=赋值完美地破坏了刚才我们期望的listener之间的相互关系。
如何实现一个event?
我们这里简单列出一个完整的event实例,然后就这个实例来讨论核心问题INotifyPropertyChanged。
public class ValueChangedEventArgs : System.EventArgs
{
public readonly int oldValue;
public readonly int newValue;
public ValueChangedEventArgs(int oldOne, int newOne)
{
oldValue = oldOne;
newValue = newOne;
}
}
public class Commodity
{
string symbol;
int volume;
public event EventHandler<ValueChangedEventArgs> ValueChanged;
protected void OnValueChanged(ValueChangedEventArgs e)
{
if (ValueChanged != null)
{
ValueChanged(this, e);
}
}
public int Volume
{
get { return volume; }
set
{
if (volume == value) { return; }
int oldValue = volume;
volume = value;
OnValueChanged(new ValueChangedEventArgs(oldValue, volume);
}
}
class Test
{
static void Main()
{
Commodity c = new Commodity(“600000”);
c.Volume = 100;
c.ValueChanged += commodity_ValueChanged;
c.Volume = 200;
}
static void commodity_ValueChanged(object sender, ValueChangedEventArgs e)
{
Console.WriteLine(“Volume Changed!”);
}
}