首页 > 其他分享 >使用MVVM Toolkit简化WPF开发

使用MVVM Toolkit简化WPF开发

时间:2023-12-23 22:47:24浏览次数:29  
标签:string MVVM ViewModel Toolkit WPF public

最近. NET 8 的 WPF 推出了 WPF File Dialog改进,这样无需再引用 Win32 命名空间就可以实现文件夹的选择与存储了,算是一个很方便的改进了。顺手写了一个小的 WPF 程序,在使用 Model-View-ViewModel(MVVM) 模式的时候,我不想使用 Prism 等重量级的框架,找了一个轻量级的 MVVM Community Toolkit (以下简称 MVVM Toolkit)。

在现代 WPF 应用程序开发中,遵循 MVVM(Model-View-ViewModel)模式已成为一种标准做法。MVVM 模式视图和逻辑分离,提高了代码的可测试性、可维护性。

MVVM Toolkit 核心功能

MVVM Toolkit 提供了一系列的功能,使得在 WPF 等程序中实现 MVVM 更加简单。

  1. ViewModel 基类:基类(例如 ObservableObject)为实现属性更改通知提供了基础结构,简化了 ViewModel 的创建过程。
  2. 命令的实现:MVVM Toolkit 提供了易于使用的命令实现(RelayCommand ),允许 View 以声明方式绑定到 ViewModel 上的方法。
  3. 弱消息机制:弱消息机制(WeakReferenceMessenger)允许不同对象之间收发消息,而不会造成内存泄漏。

安装

使用 nuget 安装到 WPF 项目中即可。由于 MVVM Toolkit 面向. NET Standard,所以可在任何应用平台上使用:UWP、WinForms、WPF、Xamarin、Uno 等。

Install-Package CommunityToolkit.Mvvm

代码生成

在 MVVM Toolkit 中,代码生成器扮演着重要的角色。通过利用代码生成器,它能够自动化诸如属性更改通知和命令实现等常见任务,减少样板代码,提高开发效率。

例如,开发者可以通过简单的属性标记,自动实现 INotifyPropertyChanged 接口:

partial class MyViewModel : ObservableObject
 {
     [ObservableProperty]
     private string name;

     [ObservableProperty]
     private bool isEnabled;
 }

以上代码会通过 Roslyn 的代码生成器功能生成如下代码:

 partial class MyViewModel
 {
     public string Name
     {
         get => name;
         set => SetProperty(ref name, value);
     }

     public bool IsEnabled
     {
         get => isEnabled;
         set => SetProperty(ref isEnabled, value);
     }
 }

在没有 MVVM Toolkit 的情况下,开发者需要手动实现 MVVM 的各个部分。例如,实现 INotifyPropertyChanged 接口通常涉及创建大量样板代码:

public class MyViewModel : INotifyPropertyChanged
{
    private string myProperty;

    public string MyProperty
    {
        get => myProperty;
        set
        {
            myProperty = value;
            OnPropertyChanged(nameof(MyProperty));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

相比之下,MVVM Toolkit 不仅减少了需要编写的代码量,也降低了出错的可能性,使得开发更加专注于业务逻辑本身。

使用 MVVM Toolkit 创建 ViewModel

依赖属性与命令

以下是使用 MVVM Toolkit 创建 ViewModel 的一个简单示例:

public partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    private string title = "Hello, MVVM Toolkit!";

    [RelayCommand]
    private void DealWithData()
    {
        // 数据处理逻辑
    }
}

ObservableProperty 和 RelayCommand 属性标记自动处理了属性更改通知和命令实现的细节,开发者只需关注业务逻辑,并在 XAML 中绑定对应的属性/命令,组件会自动生成对应的依赖属性。

注意,请一定使用 camelCase 命名法(可以带前导_),代码生成器会生成符合 PascalCase 标准的属性/方法名称。

弱引用消息

再看 WeakReferenceMessenger 在不同 ViewModel 或组件间发送和接收消息:

1. 定义消息类型

首先定义一个消息类型。消息可以是任何类或结构,通常包含发送者想要传递的数据:

public class MyMessage
{
    public string Text { get; }

    public MyMessage(string text)
    {
        Text = text;
    }
}

2. 发送消息

在一个 ViewModel 或组件中,你可以发送消息。假设有一个 SenderViewModel

public class SenderViewModel
{
    private void SendMessage()
    {
        var message = new MyMessage("Hello from SenderViewModel");
        WeakReferenceMessenger.Default.Send(message);
    }
}

SendMessage 方法创建了一个 MyMessage 实例,并通过 WeakReferenceMessenger.Default.Send 方法发送。

3. 接收消息

在另一个 ViewModel 或组件中,你可以注册以接收特定类型的消息。例如,你可能有一个 ReceiverViewModel

public class ReceiverViewModel
{
    public ReceiverViewModel()
    {
        // 注册以接收 MyMessage 类型的消息
        WeakReferenceMessenger.Default.Register<MyMessage>(this, (recipient, message) =>
        {
            // 处理接收到的消息
            string receivedText = message.Text;
            // Do something with receivedText
        });
    }
}

在 ReceiverViewModel 的构造函数中,使用 WeakReferenceMessenger.Default.Register 方法注册了消息接收器,当发送方发送 MyMessage 类型的消息时,这个接收器将被调用。

4. 解除消息注册

在不再需要接收消息时,或者在对象被销毁之前,应该解除消息的注册,以避免内存泄漏:

public class ReceiverViewModel
{
    public ReceiverViewModel()
    {
        WeakReferenceMessenger.Default.Register<MyMessage>(this, OnMessageReceived);
    }

    private void OnMessageReceived(object recipient, MyMessage message)
    {
        // 处理消息
    }

    ~ReceiverViewModel()
    {
        WeakReferenceMessenger.Default.Unregister<MyMessage>(this);
    }
}

ReceiverViewModel 通过其析构函数取消注册(也可以使用 IDispose 实现),确保当 ViewModel 被回收时,不会有消息处理器的引用残留。

总结

MVVM Toolkit 为 WPF 开发者提供了一个强大且易用的工具,它极大地简化了 MVVM 模式实现过程,虽然其他框架(MVVM Light/Prism 等)也提供了类似功能,但它非常轻量,使用简单,非常适合小型工程使用。

标签:string,MVVM,ViewModel,Toolkit,WPF,public
From: https://www.cnblogs.com/chinasoft/p/17923770.html

相关文章

  • 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发
    https://www.cnblogs.com/wuhuacong/tag/WPF/ 在我们的SqlSugar的开发框架中,整合了Winform端、Vue3+ElementPlus的前端、以及基于UniApp+Vue+ThorUI的移动前端几个前端处理,基本上覆盖了我们日常的应用模式了,本篇随笔进一步介绍前端应用的领域,研究集成WPF的应用端,循序渐进介绍基......
  • WPF MvvmToolkit入门
    最新.net6wpfMVVMToolkit8.0工程搭建。MVVMToolkit是一个轻量级MVVM框架,在框架下我们第一个要做的就是搞清在此框架下的一些常规操作:属性绑定和通知,命令绑定,消息传递。搞懂这些处理流程,然后就可以写自己业务的逻辑。1.安装mvvmtoolkit1.1Nuget下载CommunityToolkit.Mvvm......
  • [WPF] 使用 MVVM Toolkit 构建 MVVM 程序(CommunityToolkit.Mvvm)
    1.什么是MVVMToolkit模型-视图-视图模型(MVVM)是用于解耦UI代码和非UI代码的UI体系结构设计模式。借助MVVM,可以在XAML中以声明方式定义UI,并使用数据绑定标记将UI链接到包含数据和命令的其他层。微软虽然提出了MVVM,但又没有提供一个官方的MVVM库(多年前有过......
  • WPF+SqlSugar+MVVM实现增删改查
    1、新建一个WPF应用(NETFramework)2、安装SqlSugarNuGet包3、在SqlSugar4.x下载代码生成器https://www.donet5.com/Doc/8/11374、在WPF中新建三个文件夹Models主要放实体类、Views主要放窗体、ViewModels主要是View逻辑的实现5、把生成的实体类放到Models文件夹内,在V......
  • 浅谈WPF之DataGrid过滤,分组,排序
    使用过Excel的用户都知道,Excel可以方便的对数据进行分组,过滤,排序等操作,而在WPF中,默认提供的DataGrid只有很简单的功能,那么如何才能让我们开发的DataGrid,也像Excel一样具备丰富的客户端操作呢?今天就以一个简单的小例子,简述如何在WPF中实现DataGrid的过滤,筛选,排序等功能。仅供学习分......
  • wpf + LiveCharts.wpf 做个漂亮的图表
    十年河东,十年河西,莫欺少年穷学无止境,精益求精参考:WPFLiveChart图表详解接着上一篇博客: wpf+MaterialDesign+Prism8实现导航功能 1、项目引入图表包 2、定义用户控件IndexView的IndexViewModel,如下usingLiveCharts;usingPrism.Mvvm;usingSystem;using......
  • wpf + MaterialDesign + Prism8 实现导航功能
    十年河东,十年河西,莫欺少年穷学无止境,精益求精实现的效果: 1、初始化Prism 1.1、项目引入如下包 1.2、按照Prism规则,项目中创建如下文件夹 Prism规则:必须将窗体放入Views文件夹中,窗体名称必须以View结尾,必须将数据上下文放入ViewModels文件夹中,上下文类必须以Model结......
  • CommunityToolkit.Mvvm 之 通过一个属性控制一个按钮是否禁用 及 按钮执行费时需任务
    要达到的目的:通过一个属性控制一个按钮是否禁用当按钮执行费时需任务时,按下禁用按钮,任务完成后自动解除禁用1. 属性定义1[ObservableProperty]2[NotifyCanExecuteChangedFor(nameof(SettingParamCommand))]//属性变化时通知对应的命令3privateboolallowOperator;2.......
  • WPF中通过附加属性实现任意控件拖动调整大小
    publicclassResizeBehavior{//附加属性用于标识控件是否可调整大小publicstaticreadonlyDependencyPropertyIsResizableProperty=DependencyProperty.RegisterAttached("IsResizable",typeof(bool),typeof(ResizeBehavior),newP......
  • wpf 元素设置焦点无效的问题
    首先确定元素的Enabled, Visible, Loaded,and Focusable这四个属性,如果这些属性的任何一个为false,则不能设置焦点到该元素上。如果Focusable为false,设置焦点的方式可以先在鼠标左键按下事件中,设置Focusable,如下:userControl.MouseLeftButtonDown+=delegate{userCo......