WPF MVVM框架MvvmLight使用入门
介绍
MVVM Light是WPF的一个mvvm框架,目前已经停止维护,适用于Net framework版本下的WPF程序,如果要在net5或者更新的net版本使用,可以使用新的**CommunityToolkit.Mvvm
**包,它是 .NET 社区工具包的一部分,用法和MvvmLight类似。
项目地址:https://github.com/lbugnion/mvvmlight
MvvmLight安装和准备
在Nuget中搜索MvvmLight进行安装
安装完成后,在项目目录里自动生成了ViewModel文件夹,生成两个文件,一个MainViewModel.cs
可以作为MainWindow的viewModel,另一个ViewModelLocator.cs
作为ViewModel定位器,通过Ioc容器,在改文件中获取ViewModel的实例。
ViewModelLocator.cs
中有报错,只需要重新引用using CommonServiceLocator;
,删除using Microsoft.Practices.ServiceLocation;
就可以了。
修改之后:
在App.xaml
中增加了一个Locator,可以作为静态资源使用,用于后面绑定
<vm:ViewModelLocator
xmlns:vm="clr-namespace:WpfMvvmLightExample.ViewModel"
x:Key="Locator"
d:IsDataSource="True" />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XGQzBqxx-1679585878912)(https://secure2.wostatic.cn/static/gCMK56cP4peWpDumy9Az3u/image.png?auth_key=1679585438-vKaKnNSngqPmZn49LU1oMZ-0-a6a800cf02d8f935816dbdc1e95bfb85)]
框架常用的类介绍
ObservableObject
类,继承INotifyPropertyChanged
接口,实现了基本的属性推送功能,如果有需要推送的Model类可以继承于该类
ViewModelBase
类,ViewModel
基类,继承自ObservableObject
类,针对ViewModel
对一些方法进行封装优化。
RelayCommand
和RelayCommand<>
类,该框架中常用的命令类,用于在ViewModel
实现命令
IMessenger
和Messenger
,消息交互类,类似事件集合器用于ViewModel
和View
,ViewModel
之间的消息交互。
SimpleIoc
类,是该框架中实现的简单Ioc容器,主要在ViewModelLocator
中用于ViewModel
的注册和实例化
使用
View和ViewModel绑定
要将MainViewModel
和MainWindow
绑定起来,只需要在MainWindow
上增加绑定DataContext="{Binding Source={StaticResource Locator},Path=Main}"
,如下所示
绑定测试
给界面增加一些控件和ViewModel增加属性用于绑定测试
MainWindow:
<Grid>
<TextBlock
Margin="55,29,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Text="姓名"
TextWrapping="Wrap" />
<TextBox
Width="120"
Margin="95,29,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Text="{Binding Name}"
TextWrapping="Wrap" />
</Grid>
ViewModel:
public class MainViewModel : ViewModelBase
{
public string Name { get; set; }
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
Name = "lisi";
}
}
效果:
新ViewModel绑定
如果要绑定新的页面和ViewModel,在DataContext="{Binding Source={StaticResource Locator},Path=Main}"
中Path后面出现新的ViewModel对象,则需要在ViewModelLocator.cs
文件中注册新的ViewModel,并添加新的属性
//注册
SimpleIoc.Default.Register<AboutWindowViewModel>();
//ViewModel 属性
public AboutWindowViewModel About
{
get
{
return ServiceLocator.Current.GetInstance<AboutWindowViewModel>();
}
}
后台数据绑定推送
使用基类中的方式进行属性推送
方式一:
使用: RaisePropertyChanged
实现了基本INotifyPropertyChanged
接口基本的属性变化推送。该方法位于ObservableObject
类中
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
//方式一:
RaisePropertyChanged();
}
}
方式二:
使用Set<>()
方法进行推送,该方法,会先对新的值value进行判断,如果跟原来值相同,则不会更新,如果不同则更新并推送。该方法位于ViewModelBase
类中
测试代码:
public class MainViewModel : ViewModelBase
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
//方式一:
//_name = value;
//RaisePropertyChanged();
//方式二:
Set(ref _name, value);
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
Name = "lisi";
ThreadPool.QueueUserWorkItem(ChangeName);
}
void ChangeName(object o)
{
Thread.Sleep(10000);
Name = "改名了";
}
}
效果:
动态更新前台的数据
命令绑定
主要使用RelayCommand
和RelayCommand<>
类实现命令,并绑定,即可实现。
如下实现一个命令:
public ICommand ChangeNameCmd
{
get
{
return new RelayCommand<object>(o =>
{
Name = "命令改名";
});
}
}
增加一个按钮,使用Command
绑定命令,
<Button
Margin="243,29,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Command="{Binding ChangeNameCmd}"
Content="修改" Width="51" />
运行效果:
点击之后即可改变属性