自从上一次写MVVM入门到现在,又过了好长时间了,一直想着把事件的绑定总结一下,但是一来是认识的不够,感觉讲不清楚;二来是懒。不管了,写的不对的地方大家提一下,错误要是不暴露它就一直是错误。
先说按钮的事件绑定,.net中提供的ICommand就是这么用的,自己写一个command的基类,继承
ICommand,实现ICommand的3个方法,最简单的实现:
1 public classCommandBase: ICommand 2 { 3 readonlyAction _excuteMethod; 4 //设置按钮的可用性 5 public bool CanExecute(objectparameter) 6 { 7 return true; 8 } 9 10 public eventEventHandler CanExecuteChanged 11 { 12 add 13 { 14 CommandManager.RequerySuggested +=value ; 15 16 } 17 remove 18 { 19 CommandManager.RequerySuggested -=value ; 20 } 21 } 22 23 //按钮的执行事件 24 public void Execute(objectparameter) 25 { 26 _excuteMethod(); 27 } 28 #endregion 29 }
这段代码中,CanExecuteChanged是重点,注册事件和移除事件。
Execute在按钮点击的时候执行,使用下边的代码,按钮的事件就绑定了。
1 publicICommand CloseCommand 2 { 3 get 4 { 5 return newCommandBase(); 6 } 7 }
但是这样,按钮是什么操作都不会做的,实现了也没有任何实际意义。在按钮点击的执行方法里面,执行了一个默认的action,action是一个委托类,所以,可以在构造的时候传一个委托的具体实现方法,构造函数加一个参数,改造一下,基类里面添加一个构造函数,然后就可以使用自己定义的方法了。
1 publicCommandBase(Action excuteMethod) 2 { 3 if (excuteMethod == null) 4 { 5 throw newException(); 6 } 7 _excuteMethod =excuteMethod; 8 9 } 10 11 publicICommand CloseCommand 12 { 13 get 14 { 15 return newCommandBase(Close); 16 } 17 } 18 voidClose() 19 { 20 21 }
代码写的有点啰嗦,不过,总体来说,是我认识的一个过程。
下一个问题,commandbase基类中的代码是怎么执行的?
get完毕,CloseCommand绑定事件,然后执行CanExecuteChanged,注册事件。
CanExcute是怎么执行的?输出窗口提示, 单步执行: 正在逐过程执行非用户带代码“System.Windows.Controls.Primitives.ButtonBase.HookCommand”,msdn上说这个命名空间在PresentationFramework.dll中,用reflector看了下也没找到,o(╯□╰)o,先记下这个问题。
**************************************************************************************
依赖项通知,在文字改变的时候,通知界面,主要用到INotifyPropertyChanged,定义一个
继承INotifyPropertyChanged的基类。
1 public eventPropertyChangedEventHandler PropertyChanged; 2 3 public delegate void ContextChangedEventHandler(objectsender); 4 public eventContextChangedEventHandler ContextChanged; 5 6 protected void OnPropertyChanged(stringpropertyname) 7 8 9 { 10 if (ContextChanged != null) 11 12 13 { 14 15 16 ContextChanged(propertyname); 17 18 19 } 20 21 if (PropertyChanged != null) 22 23 24 PropertyChanged( this, newPropertyChangedEventArgs(propertyname)); 25 26 27 }
按钮content绑定value属性即可。
1 public stringValue 2 { 3 get 4 { 5 return_value; 6 }
本来想写一下,文字改变之后添加一个自定义的事件,想了想还是算了,在viewmodel中value的set里面直接写方法就行了,以后发现什么情况要用的话再做吧。