前段时间一直在学习MVC,工作需要,现在需要180度急转弯,搞WPF,MVVM,只能找资料学习了。
WPF中有一个消息机制,就是当前台控件绑定的值改变时,会自动通知到指定的事件来改变VM的值,反之亦然。
这个机制实际上是一个接口:INotifyPropertyChanged
凡是要实现这种自动跟随变化的都要实现这个接口,这个接口只有一个成员,是一个事件:
public event PropertyChangedEventHandler PropertyChanged;
配合它,要自己写一个方法:
private void RaisePropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler!=null) { handler(this,new PropertyChangedEventArgs(propertyName)); } }
CallerMemberName这个标记很好玩,可以自动赋值给后边的参数,赋的值就是调用此方法的属性,并且在调用的时候不用指定是哪个属性,很方便。
是在这篇文章中学到的。
上全码:
public class SongViewModel : INotifyPropertyChanged { public SongViewModel() { Song = new Song { ArtistName = "NoName", SongTitle = "NoName" }; } private int _count = 0; private Song Song { set; get; } public string ArtistName { get { return Song.ArtistName; } set { if (Song.ArtistName!=value) { Song.ArtistName = value; RaisePropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler!=null) { handler(this,new PropertyChangedEventArgs(propertyName)); } } }
还有一个重要接口是:ICommand
使用它,就可以不必再像以往一样绑定按钮的click事件来实现改变值了。
现在用绑定控件的command事件来达到同样的效果,WPF页面的CS页无须写任何代码,一切操作都在ViewModel中。
以上代码再添加点:
private bool CanExecute() { return true; } private void Execute() { ArtistName = string.Format("snake{0}", ++_count); } public ICommand UpArtistName { get { return new RelayCommand(Execute, CanExecute); } }
RelayCommand是自己定义的继承自ICommand的类,那两个方法是所需要的参数
操作就放在Execute中就可以了
CanExecute中放是否允许此命令执行的逻辑
具体RelayCommand代码如下:
public class RelayCommand:ICommand { private Func_canExecute ; private Action _execute; public RelayCommand(Action execute):this(execute,null) {} public RelayCommand(Action execute, Func canExecute) { if (execute==null) { throw new ArgumentNullException("execute"); } _canExecute = canExecute; _execute = execute; } public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(); } public event System.EventHandler CanExecuteChanged { add { if (_canExecute!=null) { CommandManager.RequerySuggested += value; } } remove { if (_canExecute!=null) { CommandManager.RequerySuggested -= value; } } } public void Execute(object parameter) { _execute(); } }
以上学习取自: