• WPF -- MVVM框架 - CommunityToolkit.Mvvm


    目录

    1. 简介

    2. Nuget安装

    3. 开发环境

    4. 属性通知

    5. 命令

    5.1 RelayCommand

    5.2 AsyncRelayCommand

    6. Messenger

    7. Ioc

    8. 其他

    8.1 global using

    8.2 函数参数null检查


    1. 简介

    包 CommunityToolkit.Mvvm (名为 MVVM 工具包) 是一个现代、快速和模块化的 MVVM 库。 它是 Windows 社区工具包的一部分。

    MVVM 工具包由 Microsoft 维护和发布,也是 .NET Foundation 的一部分。

    MVVM 工具包还具有 .NET 6 目标,用于在 .NET 6 上运行时启用更多内部优化。

    2. Nuget安装

     

    3. 开发环境

    VS2022

    WPF应用程序

    .NET6.0

    4. 属性通知

    添加引用 using CommunityToolkit.Mvvm.ComponentModel;

    1. //viewModel继承ObservableObject
    2. public class ViewAViewModel:ObservableObject
    3. {
    4. private string _name;
    5. public string Name
    6. {
    7. get => _name;
    8. set => SetProperty(ref _name, value);
    9. }
    10. }

    5. 命令

    添加引用 using CommunityToolkit.Mvvm.Input;

    5.1 RelayCommand

    1. public IRelayCommand SendCommand { get; }
    2. SendCommand=new RelayCommand(Send);
    3. private void Send()
    4. {
    5. }

    5.2 AsyncRelayCommand

    支持异步操作

    1. public IAsyncRelayCommand LoadCommand { get; }
    2. LoadCommand = new AsyncRelayCommand(LoadAsync);
    3. private async Task<string> LoadAsync()
    4. {
    5. await Task.Delay(TimeSpan.FromSeconds(5));
    6. return "Load Success";
    7. }

     ExecutionTask属性可监视操作进度,可获取方法执行返回值等

    IsRunning属性:检查操作完成时间

    ViewA.xaml

    1. <Window.Resources>
    2. <con:TaskResultConverter x:Key="TaskResultConverter"/>
    3. <con:BoolToVisibleConverter x:Key="BoolToVisibleConverter"/>
    4. Window.Resources>
    5. <StackPanel Grid.Row="1" Orientation="Vertical">
    6. <TextBlock Margin="5">
    7. <Run Text="Task status:"/>
    8. <Run Text="{Binding LoadCommand.ExecutionTask.Status, Mode=OneWay}"/>
    9. <LineBreak/>
    10. <Run Text="Result:"/>
    11. <Run Text="{Binding LoadCommand.ExecutionTask, Converter={StaticResource TaskResultConverter}, Mode=OneWay}"/>
    12. TextBlock>
    13. <ProgressBar IsIndeterminate="True" Visibility="{Binding LoadCommand.IsRunning,Converter={StaticResource BoolToVisibleConverter}, Mode=OneWay}" Width="200" Height="20" HorizontalAlignment="Left" Margin="5" />
    14. <Button Content="AsyncCommand" Command="{Binding LoadCommand}" Width="200" Height="100" HorizontalAlignment="Left" Margin="5"/>
    15. StackPanel>

     TaskResultConverter

    1. public class TaskResultConverter : IValueConverter
    2. {
    3. public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
    4. {
    5. if (value is Task<string> val && val.IsCompleted)
    6. {
    7. return val.Result;
    8. }
    9. return null;
    10. }
    11. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    12. {
    13. throw new NotImplementedException();
    14. }
    15. }

    BoolToVisibleConverter

    1. public class BoolToVisibleConverter : IValueConverter
    2. {
    3. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    4. {
    5. if (value is bool val)
    6. {
    7. return val ? Visibility.Visible : Visibility.Collapsed;
    8. }
    9. return Visibility.Collapsed;
    10. }
    11. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    12. {
    13. throw new NotImplementedException();
    14. }
    15. }

    效果:

     

     

    6. Messenger

    接口 IMessenger 是可用于在不同对象之间交换消息的类型协定。

    MVVM Toolkit提供现装实现:WeakReferenceMessenger在内部使用弱引用,为收件人提供自动内存管理。StrongReferenceMessenger使用强引用,并且要求开发人员在不再需要接收者时手动取消订阅收件人

    消息可以是数据类型或者自定义实体

    1. public class InfoMessage
    2. {
    3. public string Title { get; set; }
    4. public string Message { get; set; }
    5. public int Id { get; set; }
    6. public DateTime Date { get; set; }
    7. }

    添加引用 using CommunityToolkit.Mvvm.Messaging;

    注册消息

    1. WeakReferenceMessenger.Default.Register(this, (r, m) =>
    2. {
    3. //do something
    4. messageService?.ShowMessage(this, $"收到消息:{m.Message} Date:{m.Date}");
    5. });

    发送消息

    1. WeakReferenceMessenger.Default.Send(new InfoMessage()
    2. {
    3. Date = DateTime.Now,
    4. Message="AAA"
    5. });

    取消注册

    WeakReferenceMessenger.Default.UnregisterAll(this);

    7. Ioc

      使用依赖项注入,它包括创建大量注入后端类的服务,这允许使用这些服务的代码不依赖于这些服务的实现详细信息,并且还可以轻松地交换这些服务的具体实现。

      此模式还使平台特定的功能更易于后端代码使用,方法是通过服务进行抽象化,然后在需要时注入这些功能。

     使用平台API:Ioc

    添加引用 using CommunityToolkit.Mvvm.DependencyInjection;

                    using Microsoft.Extensions.DependencyInjection;

    1. public partial class App : Application
    2. {
    3. private Mutex mutex;
    4. protected override void OnStartup(StartupEventArgs e)
    5. {
    6. //防止程序多开
    7. mutex = new Mutex(true,nameof(MVVMDemo),out bool ret);
    8. if(!ret)
    9. {
    10. MessageBox.Show("软件已经在运行中,请检查!!");
    11. Environment.Exit(0);
    12. }
    13. InitialServices();
    14. new ViewA().Show();
    15. base.OnStartup(e);
    16. }
    17. private void InitialServices()
    18. {
    19. var services = new ServiceCollection();
    20. //单一实例服务 每一次获取的对象都是同一个
    21. services.AddSingleton();
    22. //暂时性服务 请求获取-(GC回收-主动释放) 获取时创建 每一次获取的对象都不是同一个
    23. services.AddTransient();
    24. var provider = services.BuildServiceProvider();
    25. Ioc.Default.ConfigureServices(provider);
    26. }
    27. }

     服务

    1. public interface IMessageService
    2. {
    3. void ShowMessage(object owner, string message);
    4. }
    5. public class MessageBoxCustom : IMessageService
    6. {
    7. public void ShowMessage(object owner, string message)
    8. {
    9. MessageBox.Show(message);
    10. }
    11. }

    调用:

    1. private IMessageService messageService;
    2. messageService=Ioc.Default.GetService();
    3. messageService?.ShowMessage(this, $" ");

     构造函数注入

    1. private IMessageService messageService;
    2. //“构造函数注入”,这意味着 DI 服务提供商能够在创建所请求类型的实例时自动解析已注册服务之间的间接依赖关系。
    3. public ViewAViewModel(IMessageService _messageService)
    4. {
    5. messageService = _messageService;
    6. }
    7. private void IOCTest()
    8. {
    9. //实际使用时并没有传入IMessageService 的实例,但可以使用,因为IOC框架自动注入
    10. messageService?.ShowMessage(this, "IOC测试");
    11. }

    调用

    1. public ViewA()
    2. {
    3. InitializeComponent();
    4. DataContext = Ioc.Default.GetService();
    5. }

    8. 其他

    8.1 global using

    C#10新功能,新建文件GlobalUsing.cs

    使用关键字 global 标识 using 指令,则 using 适用于整个项目

    1. global using System;
    2. global using System.Threading;
    3. global using System.Threading.Tasks;
    4. global using System.Windows.Data;
    5. global using System.Globalization;
    6. global using System.Windows;
    7. global using CommunityToolkit.Mvvm.ComponentModel;
    8. global using CommunityToolkit.Mvvm.DependencyInjection;
    9. global using CommunityToolkit.Mvvm.Input;
    10. global using CommunityToolkit.Mvvm.Messaging;
    11. global using Microsoft.Extensions.DependencyInjection;
    12. namespace MVVMDemo;
    13. public class GlobalUsing
    14. {
    15. }

    8.2 函数参数null检查

    1. public void Show(string str)
    2. {
    3. //null检查
    4. ArgumentNullException.ThrowIfNull(str);
    5. }

    异常的时候,就会出现:System.ArgumentNullException: 'Value cannot be null. (Parameter 'str')'

    参考: Messenger - Windows Community Toolkit | Microsoft Docs

  • 相关阅读:
    每天一个数据分析题(一百六十八)
    1811_spacemacs从v.0.200.13升级到v.0.200.14的几点变化感受
    领导提拔项目经理,看的从来不是努力
    第十二届钧瓷文化旅游节主题曲:让世界看见钧瓷的魅力
    jupyter notebook插件安装及插件推荐
    vue elementui 搜索栏子组件封装
    【Arduino+ESP32专题】案例:使用INA3221监控电压电流 1
    在uniapp中为自定义组件绑定点击事件点击后没有效果
    【JUC】CompletableFuture
    SpringBoot整合Swagger
  • 原文地址:https://blog.csdn.net/a549742320/article/details/126251625