MvvmLight框架的基本使用
关于MvvmLight框架的介绍可以看这篇,说的很详细,在此记录下来以作复习,通过一个简单的例子说明MvvmLight的基本使用
https://www.cnblogs.com/3xiaolonglong/p/10001787.html
首先MvvmLight框架最大的优点就是起到分离试图(View)和模型(Model)的作用,相对于之前把逻辑结构写在Code Behind 的方式,MVVM模式几乎完全解耦了视图和逻辑业务的关系,通过数据绑定和命令绑定来处理UI属性及事件驱动;同时,ViewModel中对属性的变更也会通知到View前端,让View前端实时更新。
MVVM中,各个部分的职责如下:
Model:负责数据实体的结构处理,与ViewModel进行交互;
View:负责界面显示,与ViewModel进行数据和命令的交互;
ViewModel:负责前端视图业务级别的逻辑结构组织,并将其反馈给前端。
按照大佬的步骤安装MVVMLight,然后新建一个MVVMLight框架的WPF项目,项目中包括ViewModel文件夹,里面有MainViewModel.cs和ViewModelLocator.cs两个文件。
下面我们就首先分析下这两个文件的内容:
MainViewModel.cs文件分析:
MainViewModel.cs文件中只有一个类MainViewModel,该类是主窗口MainWindow对应的ViewModel,继承自类ViewModelBase
ViewModelBase类又继承类ObservableObject,同时实现ICleanup接口
ObservableObject类实现INotifyPropertyChanged接口,用于通知属性的改变
由此分析,我们可以得出以下一般结论:
当我们定义一个自己的ViewModel时,一般让自定义ViewModel继承自ViewModelBase类,这样当ViewModel中属性发生变化的时候,就可以自动通知对应的VIew。
ViewModelLocator.cs文件分析:
ViewModelLocator.cs文件中只有一个ViewModelLocator类,类中包括一个构造函数、一个类型为MainViewModel的Main属性、以及一个静态的Cleanup函数。
下面这个例子把MainWindow和MainViewModel名称分别改为了LoadWindow和LoadViewModel了,其他都一样。

前台xmal主要代码如下,大家可以弄一个简单的界面测试就行:

在App.xmal中的代码:
<Application x:Class="MvvmLightDemo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:MvvmLightDemo" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:vm="clr-namespace:MvvmLightDemo.ViewModel" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" StartupUri="LoadWindow.xaml"> <!--控件的顶级资源--> <Application.Resources> <ResourceDictionary> <vm:ViewModelLocator x:Key="Locator" /> </ResourceDictionary> </Application.Resources> </Application>
xmal.cs前端代码:
<Window x:Class="MvvmLightDemo.LoadWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MvvmLightDemo"
mc:Ignorable="d"
FontFamily="Arial"
FontSize="20"
WindowStyle="None"
Background="Transparent"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
<!--通过该句获取LoadViewModel示例-->
DataContext="{Binding Source={StaticResource Locator}, Path=LoadVM_Instance}"
Title="LoadWindow" Height="550" Width="700">
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Opacity="0.9" Grid.RowSpan="2">
<Border Grid.Column="1" Grid.Row="0" BorderBrush="DarkGray" BorderThickness="0 1 1 1" Panel.ZIndex="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="User Id:" FontFamily="Arial" FontSize="18" Foreground="#99F8F8F8" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0" Text="PassWord:" FontFamily="Arial" FontSize="18" Foreground="#99F8F8F8" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock>
<TextBox Text="" x:Name="txtUserId" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="6 8 10 8" Style="{DynamicResource LoadingTextBoxStyle }"></TextBox>
<PasswordBox x:Name="txtPassWord" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="6 8 10 8" Style="{DynamicResource LoadingPasswordBoxStyle}"></PasswordBox>
<Button x:Name="StartUpdate" Command="{Binding UpdateCommand}" Grid.Row="2" Content="更新用户ID" FontSize="18" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Style="{DynamicResource ButtonStyle}" Margin="45.02,0,57.933,-4.625" Width="Auto" Height="26" Grid.ColumnSpan="2"/>
<Button x:Name="btnStopUpdate" Command="{Binding StopUpdateCommand}" Grid.Row="2" Content="停止更新ID" Grid.Column="2" FontSize="18" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Style="{DynamicResource ButtonStyle}" Margin="-18.744,0,38.327,-3.125" Width="Auto" Height="26" />
</Grid>
</Grid>
</Border>
</Grid>
</Grid>
</Window>
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using GalaSoft.MvvmLight.Messaging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Threading; namespace MvvmLightDemo.ViewModel { public class LoadViewModel: ViewModelBase { private RelayCommand updateCommand; private RelayCommand stopUpdateCommand; private string userId; /// <summary> /// 属性,用户ID /// </summary> public string UserId { get { return userId; } // MvvmLight实现的Set方法,好处就是不用自己实现RaisePropertyChanged函数了,属性跟改后也可以通知到View端; set { Set(ref userId, value); } } /// <summary> /// 更新ID命令 /// </summary> public RelayCommand UpdateCommand { set { updateCommand = value; } get { if (updateCommand==null) { updateCommand = new RelayCommand(()=>ExecuteUpdate()); } return updateCommand; } } /// <summary> /// 停止更新ID命令 /// </summary> public RelayCommand StopUpdateCommand { set { stopUpdateCommand = value; } get { if (stopUpdateCommand==null) { stopUpdateCommand = new RelayCommand(()=>ExecuteStopUpdate()); } return stopUpdateCommand; } } private void ExecuteStopUpdate() {
//发送消息给View端 Messenger.Default.Send<string>("","StopUpdate"); } private void ExecuteUpdate() {
//发送消息给View端 Messenger.Default.Send<string>(UserId, "Update"); } } }
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Ioc; using Microsoft.Practices.ServiceLocation; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MvvmLightDemo.ViewModel { public class ViewModelLocator { public ViewModelLocator() { //所有的View都可以到Locator中找到自己需要的VM层,这个Locator相当于一个索引器 // Locator层返回的VM层是单例形式的,避免了由于代码问题导致的内存泄漏 ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); if (ViewModelBase.IsInDesignModeStatic) { // 在Visual Studio中设计预览Xaml文件的时候,在这里注册会起作用; SimpleIoc.Default.Register<LoadViewModel>(); } else { // 在运行时,在这里注册会起作用; SimpleIoc.Default.Register<LoadViewModel>(); } // 更多的时候,默认在这里注册就可以了; SimpleIoc.Default.Register<LoadViewModel>(); } //返回一个LoadViewModel的实例,通过前端即xmal.cs获取 public LoadViewModel LoadVM_Instance { get { return ServiceLocator.Current.GetInstance<LoadViewModel>(); } } public static void Cleanup() { // TODO Clear the ViewModels } } }
using GalaSoft.MvvmLight.Messaging; using MvvmLightDemo.Model; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; namespace MvvmLightDemo { /// <summary> /// LoadWindwo.xaml 的交互逻辑 /// </summary> public partial class LoadWindow : Window { private DispatcherTimer timerUpdate = new DispatcherTimer(); public LoadWindow() { InitializeComponent(); Messenger.Default.Register<string>(this,"Update",UpdateMethod); Messenger.Default.Register<string>(this,"StopUpdate",StopUpdateMethod); } private void StopUpdateMethod(string obj) { MessageBox.Show("停止更新"); timerUpdate.Stop(); } private void UpdateMethod(string obj) { MessageBox.Show("开始更新"); timerUpdate.Start(); } private void LoginMethod(string obj) { btnLogin_Click(null,null); } private void Title_Loaded(object sender, RoutedEventArgs e) { timerUpdate.Interval = TimeSpan.FromMilliseconds(500); timerUpdate.Tick += new EventHandler(timerUpdate_Trick); timerUpdate.Stop(); } private void timerUpdate_Trick(object sender, EventArgs e) { Random rand = new Random(); this.txtUserId.Text = rand.Next(1000).ToString(); } private void Title_Unloaded(object sender, RoutedEventArgs e) { timer.Stop(); } } }
点击更新按钮,UserId定时更新

赋源代码下载地址:
链接: https://pan.baidu.com/s/1bgxqHuGj7kCL2JUOVAr1SA 提取码: yiw6
4556
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!