關於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