1、定义
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。
M:Model(模型)数据模型,用来存储数据
V:View(UI界面)
VM:View(ViewModel)
2、设计一个简单的MVVM模型
2.1基础类(继承INotifyPropertyChanged)
当数据属性发生变化时,使UI界面能同步显示
class NotificationObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;//属性发生改变的事件处理程序
public void RasiePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
//当事件处理程序不为null时,本身作为事件源,然后发送事件数据,通知属性已经发生了改变
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
2.2命令属性(Command)
命令属性本事上是一个委托,相当于控件的一个事件(EventHandler),继承自ICommand接口
class DelegateCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
if (this.CanExecuteFunc == null)
{
return true;
}
else return this.CanExecuteFunc(parameter);
}
public void Execute(object parameter)
{
if (ExecuteAction == null)
{
return;
}
this.ExecuteAction(parameter);
}
public Action<object> ExecuteAction { get; set; }
public Func<object,bool> CanExecuteFunc { get; set; }
}
2.3 ViewModel设计
设计一个简单的加法,分析可以知道有三个数据属性(两个输入、一个结果),一个命令属性
/// <summary>
/// 窗体的ViewModel(数据属性、命令属性)
/// </summary>
class MainWindowViewModels:NotificationObject
{
#region 数据属性
private double input1;
public double Input1
{
get { return input1; }
set
{
input1 = value;
this.RasiePropertyChanged("Input1");
}
}
private double input2;
public double Input2
{
get{ return input2; }
set
{
input2 = value;
this.RasiePropertyChanged("Input2");
}
}
private double result;
public double Result { get { return result; }
set
{
result = value;
this.RasiePropertyChanged("Result");
}
}
#endregion
/// <summary>
/// 创建加法命令属性(本质委托)
/// </summary>
public DelegateCommand AddCommand { get; set; }
private void Add(object parameter)
{
this.Result = this.Input2 + this.Input1;
}
public MainWindowViewModels()
{
this.AddCommand = new DelegateCommand();
this.AddCommand.ExecuteAction = new Action<object>(this.Add);
}
}
2.4 View绑定ViewModel
<Grid x:Name="grid1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox x:Name="txtBox1" Grid.Row="0" Margin="5" Background="Bisque" Text="{Binding Input1}"/>
<TextBox x:Name="txtBox2" Grid.Row="1" Margin="5" Background="Bisque" Text="{Binding Input2}"/>
<TextBox x:Name="txtBox3" Grid.Row="2" Margin="5" Background="Bisque" Text="{Binding Result}"/>
<Button x:Name="btnAdd" Grid.Row="5" Content="ADD" Width="80" Height="30" Command="{Binding AddCommand}"/>
</Grid>