MVVM即模型-视图-视图模型 ,是用于解耦 UI 代码和非 UI 代码的 设计模式。 借助 MVVM,可以在 XAML 中以声明方式定义 UI,将 UI使用数据绑定标到包含数据和命令的其他层。 数据绑定提供数据和结构的松散耦合,使 UI 和链接的数据保持同步,同时可以将用户输入路由到相应的命令。
MVVM模式由M(Model),V(View),VM(ViewModel)三部分组成,其设计模式类似为MVC开发模式。目的是解耦UI和代码,编译编辑和修改。
通常一个View对应一个ViewModel,一个ViewModel可能包含n个model。
实际应用过程中可以对View中的不同控件绑定不同的ViewModel,变成一对多的模式。
View即UI界面,wpf使用xaml编,xaml是在xml的基础上开发的,整体风格与xml有诸多类似之处。
View界面中需要通过数据绑定将具体的数据绑定到ViewModel的对应属性上。
如上XAML中将DataGrid的ItemsSource属性绑定到列表,同时将对应列的数据绑定到列表的不同属性数据上。
按钮不设置Click事件,该有使用Command属性绑定具体的方法,进而调用,同时使用CommandParameter属性传递UI界面参数给ViewModel,以便后台可以访问View的控件进行相关操作。
如果可以一般ViewModel不建议访问View中的控件,以便完全剥离UI和后台代码,便于移植。
通过设置窗体的DataContext属性绑定具体的ViewModel,此方法不需要后台实现ViewModel之后再绑定,可以直接系统实现ViewModel。
DataContext="{DynamicResource vm:AddSubItemViewModel}"
Xaml设置DataContext属性时需要单列绑定
///
/// 构造函数
///
public AddSubItemWindow()
{
InitializeComponent();
this.DataContext = new AddSubItemViewModel();
}
也可以在后台用用代码进行设置,再构造函数里用构造函数绑定ViewModel。
一般一个界面设定窗体的DataContext属性,不过实际使用可以对不同的孔家设置不同的DataContext属性。
ViewModel即View和Model的中间层,用于中转界面和具体实现代码。
ViewModel用于被绑定的数据需要使用INotifyPropertyChanged接口,才能做到UI界面和后台数据的实时变更通知,ViewModel数据更新后实时刷新界面View的数据。
public class BaseNotifyPropertyChanged : INotifyPropertyChanged
{
///
/// 实现接口
///
public event PropertyChangedEventHandler PropertyChanged;
///
/// 属性变更事件
///
/// 事件源
public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
配置[CallerMemberName]属性可以自动获取属性名称作为委托参数的名称,省去代码调用时需要一个个输入委托参数名称。
///
/// private button enabled state.
///
private bool _isBtnEnabled = true;
///
/// Button enabled state.
///
public bool IsBtnEnabled
{
get
{
return _isBtnEnabled;
}
set
{
_isBtnEnabled = value;
OnPropertyChanged();
}
}
先定义一个内部私有属性,然后定义一个public属性,通过get,set获取私有类。设置属性值时调用“OnPropertyChanged()”方法通知界面刷新数据。
///
/// private subitem list.
///
private ObservableCollection _subitemList = new ObservableCollection();
///
/// Subitem list.
///
public ObservableCollection SubitemList
{
get
{
return _subitemList;
}
set
{
_subitemList = value;
OnPropertyChanged();
}
}
绑定列表时一般使用ObservableCollection
当然,如果不需要数据实时刷新时,可以直接绑定DataTable或者List
绑定事件需要继承ICommand类,通过ICommand实现事件。
///
/// Base command class.
///
/// 通过事件委托,以便跨线程调用
public class BaseCommand : ICommand
{
///
/// Event handler
/// 事件出发时先调用CanExecute(),然后调用
///
public event EventHandler CanExecuteChanged;
///
/// Execute action.
///
public Action
ICommand接头实例化时会先调用一次CanExecuteChanged,然后出发方法后先调用一次CanExecuteChanged,然后调用Execute类。
该BaseCommand类实现两个方法,然后将事件通过委托外传,ViewMode可以为具体事件绑定不同的方法。
///
/// 构造函数
///
public AddSubItemViewModel()
{
//Relate to export data method.
ExportDataCommand = new BaseCommand()
{
DoExecute = new Action(ExportData)
};
}
///
/// Export data.
///
///
public void ExportData(object obj)
{
IsBtnEnabled = false;
FileIO.ExportData();
}
先实现指令类,然后再构造函数中管理具体的实现方法,再在函数中调用具体的处理函数。
Model类是一个个具体处理的类,包括各种处理函数等实体类,通过ViewModel进行调用。