学习小结:MVVM简单事例
MVVM学习小结
一般思路
得到一个问题,首先得建模,也就是程序中的Model部分,Model的建立主要要细致分析好界面的最根本属性,然后根据所需要的属性建立模型,即对应的类及其属性;
其次,是建立和界面对应的ViewModel,一般来说ViewModel和View界面元素是一一对应的,如果使用Prism框架,则可以引入Prism后直接调用DatagateCommand(用于事件的关联执行)和NotifycationObject(用于关注的后台属性改变后通知界面,刷新获取最新属性消息),否则应该先建立DataCommand和NotifycationObject类,同时使ViewModel继承自NotifycationObject;
接下来是把界面的DataContext用ViewModel类初始化,即ViewModel提供对应界面的数据上下文;
最后,把对应的属性和事件绑定到界面(XAML代码中)
总之,问题得到,然后建模和写方法,并用特定的类把界面和后台关联起来
一个简单的例子:实现输入两个数,然后执行加减乘除,结果输出,不考虑验证之类的逻辑,例子的建设过程和上面的思路对应:
建立一个WPF项目MyMvvmDemo.Client,然后建立Models、Command、ViewModels三个文件夹 ,分析界面元素,得出界面需求为两个输入、一个输出、四个事件,顾Model可以这样建
class Model
{
public double input1 { get; set; }
public double input2 { get; set; }
public double resualt { get; set; }
}
然后建立ViewModel部分,因为ViewModel中需要DelegateCommand绑定和执行事件,需要NotifyPropertyChanged通知界面,所以首先建立DelegateCommand类和NotifycationObject(实现INotifyPropertyChanged就可以通知界面后台的改变)类:
class DelegateCommand:ICommand
{
#region ICommand 成员
public bool CanExecute(object parameter)
{
if (this.CanExecuteFunc == null)
{
return true;
}
return this.CanExecuteFunc(parameter);
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
if (this.ExecuteAction == null)
{
return;
}
this.ExecuteAction(parameter);
}
public Action<object> ExecuteAction { get; set; }//用于承接事件的执行
public Func<object,bool> CanExecuteFunc { get; set; }//用于承接判断事件是否可以执行
#endregion
}
class NotifycationObject:INotifyPropertyChanged
{
#region INotifyPropertyChanged 成¨¦员¡À
public event PropertyChangedEventHandler PropertyChanged;
public void RasiePropertyChanged(string propertyname)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
#endregion
}
接下来建立与界面对应的ViewModle:MainWindowViewModel
class MainWindowViewModel:NotifycationObject
{
private Model model1;
public Model Pmodel1
{
get { return model1; }
set
{
model1 = value;
this.RasiePropertyChanged("Pmodel1");
}
}
public DelegateCommand AddCommand { get; set; }
public DelegateCommand MinusCommand { get; set; }
public DelegateCommand MutilCommand { get; set; }
public DelegateCommand DiviCommand { get; set; }
private Model nm;
private void Add(object para)
{
this.Pmodel1.resualt = this.Pmodel1.input1 + this.Pmodel1.input2;
//以下两步是为了触发this.RasiePropertyChanged("Pmodel1");通知界面
//如果设¦计过程¨¬中Model继承了NotifycationObject,则此步不要
nm = this.Pmodel1;
this.Pmodel1 = nm;
}
private void Minus(object para)
{
this.Pmodel1.resualt = this.Pmodel1.input1 - this.Pmodel1.input2;
nm = this.Pmodel1;
this.Pmodel1 = nm;
}
private void Divi(object para)
{
if (this.Pmodel1.input2 != 0)
{
this.Pmodel1.resualt = this.Pmodel1.input1 / this.Pmodel1.input2;
nm = this.Pmodel1;
this.Pmodel1 = nm;
}
else
{
MessageBox.Show("除数不能为0","提示",MessageBoxButton.OK,MessageBoxImage.Information);
}
}
private void Mutil(object para)
{
this.Pmodel1.resualt = this.Pmodel1.input1 * this.Pmodel1.input2;
nm = this.Pmodel1;
this.Pmodel1 = nm;
}
public MainWindowViewModel()
{
model1 = new Model();
//下面两个一组,DelegateCommand实现一个桥梁作用,XAML中绑定到控件的Command属性
//后台连接到要执行的事件
this.AddCommand = new DelegateCommand();
this.AddCommand.ExecuteAction = new Action<object>(this.Add);
this.MinusCommand = new DelegateCommand();
this.MinusCommand.ExecuteAction = new Action<object>(this.Minus);
this.MutilCommand = new DelegateCommand();
this.MutilCommand.ExecuteAction = new Action<object>(this.Mutil);
this.DiviCommand = new DelegateCommand();
this.DiviCommand.ExecuteAction = new Action<object>(this.Divi);
}
}
最后,设置界面的DataContext为MainWindowViewModel,并在XAML中绑定好属性和事件即可
问题:应该用Model继承NotifycationObject还是用ViewModel继承?