前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF开发-MVVM Toolkit框架的使用

WPF开发-MVVM Toolkit框架的使用

作者头像
码客说
发布2022-06-12 12:36:36
2.9K0
发布2022-06-12 12:36:36
举报
文章被收录于专栏:码客码客

前言

官方文档

https://docs.microsoft.com/zh-cn/dotnet/communitytoolkit/mvvm/

安装

在解决方案资源管理器中,右键单击项目,然后选择“管理NuGet包”。 搜索 Microsoft.Toolkit.Mvvm 并安装它。

代码语言:javascript
复制
Install-Package Microsoft.Toolkit.Mvvm -Version 7.1.2

添加 using 指令以使用新 API:

代码语言:javascript
复制
using Microsoft.Toolkit.Mvvm;

这个包主要提供了如下的

可观察对象

代码语言:javascript
复制
public class UserVM : ObservableObject
{
  private string name;

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

  private int age;

  public int Age
  {
    get => age;
    set => SetProperty(ref age, value);
  }
}

页面的类中添加

代码语言:javascript
复制
public partial class MainWindow : Window
{
  private UserVM userVM = new UserVM();

  public MainWindow()
  {
    InitializeComponent();
    DataContext = userVM;
    Task.Run(() =>
             {
               while (true)
               {
                 userVM.Age += 1;
                 Thread.Sleep(1000);
               }
             });
  }
}

页面中

代码语言:javascript
复制
<Grid>
  <StackPanel>
    <TextBlock FontSize="30" Text="{Binding Age}" />
  </StackPanel>
</Grid>

我们就可以看到数字就会一直递增了。

命令

页面中我们添加命令

代码语言:javascript
复制
<StackPanel Height="40" Orientation="Horizontal">
  <TextBlock FontSize="30" Text="{Binding Name}" />
  <TextBlock FontSize="30" Text="{Binding Age}" />

  <Button Command="{Binding IncrementAgeCommand}" Content="年龄递增" />
</StackPanel>

对应的ViewModel中添加命令及响应的事件

代码语言:javascript
复制
public class UserVM : ObservableObject
{
  private string name;

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

  private int age;

  public int Age
  {
    get => age;
    set => SetProperty(ref age, value);
  }

  public ICommand IncrementAgeCommand { get; }
  
  public UserVM()
  {
    IncrementAgeCommand = new RelayCommand(IncrementAge);
  }
  
  private void IncrementAge() => Age++;
}

这样只要我们点击按钮,年龄就会递增1。

消息机制

注册与发送

添加传递消息的类

代码语言:javascript
复制
public class ZMessage
{
  public int Code { get; set; }

  public string Message { get; set; }

  public ZMessage(int code, string msg)
  {
    Code = code;
    Message = msg;
  }
}

消息接收与发送

代码语言:javascript
复制
public MainWindow()
{
  InitializeComponent();
  initMessage();
}

private void initMessage()
{
  WeakReferenceMessenger.Default.Register<ZMessage>(
    this,
    (r, m) =>
    {
      Console.WriteLine("接收到信息:" + m.Message);
    }
  );

  WeakReferenceMessenger.Default.Send(new ZMessage(100, "Hello"));
}

可接收消息的类

当然我们也可以让我们的ViewModel接收消息

代码语言:javascript
复制
public class UserVM : ObservableRecipient, IRecipient<ZMessage>
{
  private string name;

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

  private int age;

  public int Age
  {
    get => age;
    set => SetProperty(ref age, value);
  }

  public UserVM()
  {
    IsActive = true;
  }

  public void Receive(ZMessage message)
  {
    Name = message.Message;
    Age = message.Code;
  }
}

这里一定要注意

  • 要继承ObservableRecipient类,实现IRecipient<>接口。
  • 只有设置IsActive = true;,才能接收消息。

我们还是在页面的类中发送消息

代码语言:javascript
复制
WeakReferenceMessenger.Default.Send(new ZMessage(18, "XiaoMing"));

页面也稍做修改

代码语言:javascript
复制
<StackPanel Orientation="Horizontal">
  <TextBlock FontSize="30" Text="{Binding Name}" />
  <TextBlock FontSize="30" Text="{Binding Age}" />
</StackPanel>

我们会发现页面上已经变更为我们发送消息的数据了。

控制反转(IOC)

添加依赖库Microsoft.Extensions.DependencyInjection

代码语言:javascript
复制
Install-Package Microsoft.Extensions.DependencyInjection -Version 6.0.0

创建我们要自动注入的类

加入如下是我们用户相关的服务

代码语言:javascript
复制
public interface IUserService
{
  string getUserName();
}

代码语言:javascript
复制
public class UserService : IUserService
{
  public string getUserName()
  {
    return "XiaoMing";
  }
}

添加注入的控制

代码语言:javascript
复制
public partial class App : Application
{
  public App()
  {
    Services = ConfigureServices();

    this.InitializeComponent();
  }

  public new static App Current => (App)Application.Current;

  public IServiceProvider Services { get; }

  private static IServiceProvider ConfigureServices()
  {
    var services = new ServiceCollection();

    services.AddSingleton<IUserService, UserService>();

    // ViewModels
    services.AddTransient<UserVM>();

    return services.BuildServiceProvider();
  }
}

其中

  • AddSingleton 单一实例服务
  • AddScoped 范围内的服务
  • AddTransient 暂时性服务

权重:

AddSingletonAddTransientAddScoped

生命周期:

  • AddSingleton 项目启动-项目关闭 相当于静态类 只会有一个 每一次获取的对象都是同一个
  • AddScoped 请求开始-请求结束 在这次请求中获取的对象都是同一个 请求时创建
  • AddTransient 请求获取-(GC回收-主动释放) 获取时创建 每一次获取的对象都不是同一个

注意:

由于AddScoped对象是在请求的时候创建的 所以不能在AddSingleton对象中使用 甚至也不能在AddTransient对象中使用

使用

代码语言:javascript
复制
private UserVM userVM = (UserVM)App.Current.Services.GetService(typeof(UserVM));
private IUserService userService = (IUserService)App.Current.Services.GetService(typeof(IUserService));

这样是不是感觉还麻烦了

但是如果我们的ViewModel是这样的

代码语言:javascript
复制
public class UserVM : ObservableObject
{
  private string name;

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

  private int age;

  public int Age
  {
    get => age;
    set => SetProperty(ref age, value);
  }

  public ICommand IncrementAgeCommand { get; }

  public IUserService userService { get; }

  public UserVM(IUserService _userService)
  {
    userService = _userService;
    IncrementAgeCommand = new RelayCommand(IncrementAge);
  }

  private void IncrementAge() => Age++;
}

这里的IUserService的实例并没有传入但是就可以用了,因为IOC框架已经自动注入了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 安装
  • 可观察对象
  • 命令
  • 消息机制
    • 注册与发送
      • 可接收消息的类
      • 控制反转(IOC)
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档