tnblog
首页
视频
资源
登录

WPF Mvvmlight初探

418人阅读 2025/4/15 15:45 总访问:3667920 评论:0 收藏:0 手机
分类: .net后台框架

.netcore

WPF Mvvmlight初探

什么是 Mvvmlight?


MVVM Light 是一个轻量级的 MVVM 框架,适用于 WPF、UWP、Xamarin 等多个平台。它由微软 MVP Laurent Bugnion 开发,旨在简化 MVVM 模式的实现,提高开发效率。MVVM Light 提供了核心的 MVVM 功能,包括数据绑定、命令处理、消息传递等

安装与配置


首先创建一个.net framework 4.7.2框架的项目。


通过 NuGet 包管理器安装 MVVM Light:

  1. Install-Package MvvmLight


安装完成后,项目中会自动生成 ViewModel 文件夹,包含 MainViewModel.cs 和 ViewModelLocator.cs 两个文件


App.xaml 中添加 ViewModelLocator 作为静态资源:

  1. <Application x:Class="WpfMvvmLightExample.App"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:local="clr-namespace:WpfMvvmLightExample"
  5. xmlns:vm="clr-namespace:WpfMvvmLightExample.ViewModel"
  6. StartupUri="View/MainWindow.xaml">
  7. <Application.Resources>
  8. <ResourceDictionary>
  9. <vm:ViewModelLocator x:Key="Locator" />
  10. </ResourceDictionary>
  11. </Application.Resources>
  12. </Application>


ViewModelLocator 通过依赖注入(IoC)容器管理 ViewModel 的实例,确保每个 ViewModel 的单例模式.
然后在MainWindow.xaml中进行绑定。

  1. <Window x:Class="WpfLearningMvvmlightApp.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:local="clr-namespace:WpfLearningMvvmlightApp"
  7. mc:Ignorable="d"
  8. DataContext="{Binding Source={StaticResource Locator},Path=Main}"
  9. Title="MainWindow" Height="450" Width="800">
  10. <Grid>
  11. </Grid>
  12. </Window>

核心功能与使用示例

数据绑定


MainViewModel.cs 中定义属性,并通过 ViewModelBase 类实现属性变更通知:

  1. public class MainViewModel : ViewModelBase
  2. {
  3. public MainViewModel()
  4. {
  5. }
  6. private string _name;
  7. public string Name
  8. {
  9. get => _name;
  10. set => Set(ref _name, value);
  11. }
  12. }


在 XAML 中绑定属性:

  1. <Window x:Class="WpfLearningMvvmlightApp.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:local="clr-namespace:WpfLearningMvvmlightApp"
  7. mc:Ignorable="d"
  8. Title="MainWindow" Height="450" Width="800">
  9. <Grid>
  10. <TextBlock Text="{Binding Name}" Margin="94,46,366,311" />
  11. </Grid>
  12. </Window>


Set 方法会自动触发 PropertyChanged 事件,通知视图更新。

命令处理


使用 RelayCommand 处理用户交互:

  1. public class MainViewModel : ViewModelBase
  2. {
  3. public MainViewModel()
  4. {
  5. UpdateNameCommand = new RelayCommand(UpdateName);
  6. }
  7. private string _name;
  8. public string Name
  9. {
  10. get => _name;
  11. set => Set(ref _name, value);
  12. }
  13. public RelayCommand UpdateNameCommand { get; }
  14. private void UpdateName()
  15. {
  16. Name = "Hello, MVVM Light!";
  17. }
  18. }


在 XAML 中绑定命令:

  1. <Button Content="Update Name" Command="{Binding UpdateNameCommand}" Margin="122,158,474,217" />


RelayCommandICommand 接口的实现,用于处理命令逻辑。


点了之后Name值发生了改变。

3. 消息传递


使用 Messenger 类实现 ViewModel 与前端 View 之间的通信,举个例子:
首先我们给TextBlock添加名称修改如下所示:

  1. <TextBlock Name="CC" Text="{Binding Name}" Margin="94,46,366,311" />


然后我们在前端页面按F7查看代码,将注册一个消息的方法,当获取到通知时改变一下CC控件的值:

  1. public MainWindow()
  2. {
  3. InitializeComponent();
  4. Messenger.Default.Register<NotificationMessage>(this, (message) =>
  5. {
  6. this.CC.Text = message.Notification;
  7. });
  8. }


然后我们修改一下MainViewModel下面的UpdateName方法,让它发送一个"Hello, MVVM Light!"消息通知:

  1. private void UpdateName()
  2. {
  3. //Name = "Hello, MVVM Light!";
  4. //发送消息给View端
  5. Messenger.Default.Send(new NotificationMessage("Hello NotificationMessage, MVVM Light!"));
  6. }


然后我们点击一下发现它发生了改变。

简单依赖注入周期管理


在ViewModelLocator中这里有返回注入的实例,如果有传入Guid.NewGuid().ToString()它将是瞬时的,每次的对象都不一样。

  1. return ServiceLocator.Current.GetInstance<MainViewModel>(Guid.NewGuid().ToString());


我们再创建一个SubViewModel,只想演示一下依赖注入时,当窗口关闭但实例仍然存在的案例示范。

  1. public class SubViewModel : ViewModelBase
  2. {
  3. public static volatile int i = 0;
  4. volatile bool flag = true;
  5. public SubViewModel()
  6. {
  7. Task.Run(() => {
  8. while (flag)
  9. {
  10. Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}Logger:日志启动!");
  11. Thread.Sleep(1000);
  12. }
  13. });
  14. i++;
  15. Console.WriteLine($"初始化{i}");
  16. }
  17. public override void Cleanup()
  18. {
  19. base.Cleanup();
  20. flag = false;
  21. }
  22. }


在ViewModelLocator中进行注册SubViewModel,并且一个Sub的单例注入。

  1. public ViewModelLocator()
  2. {
  3. ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  4. SimpleIoc.Default.Register<MainViewModel>();
  5. SimpleIoc.Default.Register<SubViewModel>();
  6. }
  7. public MainViewModel Main
  8. {
  9. get
  10. {
  11. return ServiceLocator.Current.GetInstance<MainViewModel>(Guid.NewGuid().ToString());
  12. }
  13. }
  14. public SubViewModel Sub
  15. {
  16. get
  17. {
  18. return ServiceLocator.Current.GetInstance<SubViewModel>();
  19. }
  20. }


创建一个SubWindow.xaml窗体并对其进行绑定Sub这个实例对象。

  1. <Window x:Class="WpfLearningMvvmlightApp.SubWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:local="clr-namespace:WpfLearningMvvmlightApp"
  7. mc:Ignorable="d"
  8. DataContext="{Binding Source={StaticResource Locator},Path=Sub}"
  9. Title="SubWindow" Height="450" Width="800">
  10. <Grid>
  11. </Grid>
  12. </Window>


然后在MainWindow.xaml窗体中添加一个按钮用于打开SubWindow.xaml窗体。

  1. <Button Content="测试" HorizontalAlignment="Left" Margin="453,185,0,0" VerticalAlignment="Top" Height="55" Width="160" Click="Button_Click_1"/>
  1. private void Button_Click_1(object sender, RoutedEventArgs e)
  2. {
  3. new SubWindow().Show();
  4. }


我们尝试运行一下,我们先打开我们的SubWindow窗口,然后再关闭查看是否还会进行打印输出。


窗体关闭后我们发现实例并没有释放。
接下来我们将在ViewModelLocator类中写一个静态方法进行释放其中注入的类型。

  1. public static void Cleanup<T>()
  2. where T : ViewModelBase
  3. {
  4. ServiceLocator.Current.GetInstance<T>().Cleanup();
  5. // 清楚注册
  6. SimpleIoc.Default.Unregister<T>();
  7. // 再次注册,为了下一次使用的时候是空的
  8. SimpleIoc.Default.Register<T>();
  9. }


然后我们在SubWindow.xaml类中添加SubWindow_Closed事件,进行调用释放当前的依赖注入。

  1. public partial class SubWindow : Window
  2. {
  3. public SubWindow()
  4. {
  5. InitializeComponent();
  6. this.Closed += SubWindow_Closed;
  7. }
  8. private void SubWindow_Closed(object sender, EventArgs e)
  9. {
  10. ViewModelLocator.Cleanup<SubViewModel>();
  11. }
  12. }


再次测试我们发现当SubWindow关闭的时候相关绑定的依赖注入实例也会被释放,并且不再打印输出了。


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

WPF Mvvmlight Messager学习

WPF MvvmLight Messager学习[TOC] NotificationMessage在 MVVM Light 中,NotificationMessage 是一种消息类型,用于在 Vi...

初探k8s

概念补充Deployment 是在 Pod 这个抽象上更为上层的一个抽象层,它可以定义一组 Pod 的副本数量,以及这个 Pod 的版本。一...

初探Argo

初探Argo[TOC] 什么是 Argo CD? Argo CD 是 Kubernetes 的声明性 GitOps 持续交付工具。应用程序定义、配置和环境应该是...

BGP RR路由反射与Calico的初探

BGP RR路由反射与Calico的初探[TOC] BGP RR路由反射介绍由于IBGP水平分割的存在,为了保证所有的BGP路由器都能学习到完整...

Flannel CNI初探

Flannel CNI初探[TOC] Flannel 简介Flannel是由CoreOs提出的跨主通信容器网络解决方案,通过分配和管理全局唯一容器IP以及...

python 初探神经网络(一元一次函数)学习笔记

python 初探神经网络(一元一次函数)学习笔记[TOC] B站学习课程 豆豆实验有个小蓝的生物,想吃豆豆,豆豆越大豆豆的毒性...

Outlook WebAddin初探

Outlook WebAddin初探[TOC] 安装前提首先,确保你的计算机上已安装Node.js和npm。你可以在官方网站下载并安装它们。 VS C...

HugginFace 初探

HugginFace 初探[TOC] 安装环境python环境是3.6。import sys sys.version 安装torch,简单起见,避免环境问题,并且计...

Pytorch 初探

Pytorch 初探[TOC] Pytorch简介PyTorch由 Facebook 的 AI 研究团队开发的一个开源的机器学习库,它提供了张量(tensor)计...

Cmake 初探

Cmake 初探[TOC] CMake简介CMake 是一个开源的、跨平台的构建系统(编译工具),它主要用于管理项目的构建过程。它通过使用...

WPF CommunityToolkit.Mvvm初探

WPF CommunityToolkit.Mvvm初探[TOC] 什么是 CommunityToolkit.Mvvm?CommunityToolkit.Mvvm 是一个现代化的 MVVM 框架,...
这一世以无限游戏为使命!
排名
2
文章
657
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术