CommunityToolkit.MVVM

前言

MVVM工具包,以前名为 Microsoft.Toolkit.Mvvm 由 Microsoft 维护和发布,是 .NET Foundation 的一部分。

支持:.NET Standard 2.0、 .NET Standard 2.1 和 .NET 6(UI Framework 不可知,基本使用没有问题/编译特性用不了)

注:可以当做MvvmLight的替代品 大部分方法一样

安装:

安装:Nuget -> CommunityToolkit.MVVM

常规对象

ObservableObject:通知属性

第一种:基本通知属性

和MvvmLight一模一样

public partial class MainViewModel : ObservableObject
{
    // 1、基本通知属性
    private string _value;

    public string Value
    {
        get { return _value; }
        set
        {
            SetProperty(ref _value, value);
            //_value = value;
            //this.OnPropertyChanging();
        }
    }
}

第二种:直接通过实体返回 或者赋值

public partial class MainViewModel : ObservableObject
{
    UserEntity userEntity = new UserEntity();

    // 直接通过实体返回 或者赋值
    public string UserName
    {
        get { return userEntity.userName; }
        set
        {
            userEntity.userName = value;
            this.OnPropertyChanging(nameof(UserName));
    
            // 通过 SetProperty 给 Model 赋值
            SetProperty<UserEntity, string>(userEntity.userName, value, userEntity, (entity, v) => { entity.userName = v; });
        }
    }
}
public class UserEntity
{
    public string userName { get; set; }
    public int age { get; set; }
}

第三种:异步赋值

public partial class MainViewModel : ObservableObject
{
    private TaskNotifier<int> taskValue;

    public Task<int> TaskValue
    {
        get { return taskValue; }
        set
        {
            // 异步赋值 
            SetPropertyAndNotifyOnCompletion(ref taskValue, value);
        }
    }
    
    private void Refresh()
    {
        TaskValue = new Task<int>(() => { Thread.Sleep(3000); return 1000; });
    }
}

RelayCommand/RelayCommand<T>:绑定属性

和MvvmLight一模一样

 public RelayCommand BtnCommand { get; set; }
 public MainViewModel()
 {
     BtnCommand = new RelayCommand(()=>{ });
 }

Messenger:订阅

WeakReferenceMessenger(弱订阅)/StrongReferenceMessener(强订阅)

 public MainViewModel()
 {
     BtnCommand = new RelayCommand(BtnClick);

     // 消息订阅 Token 
     WeakReferenceMessenger.Default.Register<string, string>(this, "One", (obj, str) =>
     {
         (obj as MainViewModel).Value = str;
     });
     WeakReferenceMessenger.Default.Register<string, string>(this, "Two", (obj, str) =>
     {
         (obj as MainViewModel).Value = str;
     });
     // 释放
     WeakReferenceMessenger.Default.UnregisterAll(this);
 }

 private void BtnClick()
 {
     // 触发
     WeakReferenceMessenger.Default.Send<string, string>("One", "One");
     WeakReferenceMessenger.Default.Send<string, string>("Two", "Two");
 }

IOC:容器

默认这个工具包中没有IoC对象,建议使用 ServiceCollection

实例化IOC容器:

// 实例化 IOC容器 
static ServiceCollection service = new ServiceCollection();
public static IServiceProvider Service { get; private set; }

添加IOC容器:

service.AddSingleton<MainViewModel>();

Service = service.BuildServiceProvider();

使用IOC容器中的类:

App.Service.GetService<MainViewModel>();

释放IOC容器:

service.RemoveAll<MainViewModel>();

结合关闭当前界面,释放当前ioc容器:

MainViewModel:需要继承IDisposable,重写Dispose 方法:

public class MainViewModel : ObservableObject, IDisposable
{
    public void Dispose()
    {
        // 释放资源
    }
}

在APP.xaml(写IOC注入的类)中写清除方法:

   public static void Cleanup<T>() where T : IDisposable
   {
       Service.GetService<T>().Dispose();

       service.RemoveAll<T>();
   }

在窗体界面调用:

 protected override void OnClosed(EventArgs e)
 {
     base.OnClosed(e);
     App.Cleanup<MainViewModel>();
 }

扩展对象

特性

ObservableProperty:通知属性

[ObservableProperty]
public string name;

以上代码等同于:

private string name;

public string Name
{
    get { return name; }
    set { name = value; }
}

写法注意:一般都是小写,然后工具类中自动变为大写:abcNet --> AbcNet ; _abcNet --> AbcNet ; m_abcNet --> AbcNet

所以,就算字段是name,界面可以直接使用Name来赋值。

注意:当前类需要加partial修饰符,因为当写这个特性的时候,工具类会自动生成一个文件与此类绑定,必须加修饰符进行绑定:

处理当前修饰符特性字段的变化逻辑:
 // 如何处理这个字段特性的变化set逻辑/过程
 partial void OnNameChanged(string? oldValue, string newValue)
 {
     // 处理字段变化过程

 }

 partial void OnNameChanging(string? oldValue, string newValue)
 {
     // 当字段开始变化时执行

 }

NotifyPropertyChangedFor:

修改此属性的时候,通知指定属性

[ObservableProperty]
[NotifyPropertyChangedFor("FullName")] 
//NotifyPropertyChangedFor:修改此属性的时候,通知指定属性;
//当更新name的时候,也要更新FullName 
public string name;

// 页面绑定的是FullName 属性 ,
private string FullName { get => "xh" + name; }

ObservableValidator:验证

需要验证的类一般继承ObservableValidator,然后一般是写在Model层,不是ViewModel层

NotifyDataErrorInfo:这个特性必须加,否则不会校验,关键的校验特性

其他特性和普通特性一样,没有变化

 [ObservableProperty]
 [NotifyDataErrorInfo] //NotifyDataErrorInfo:关键的校验特性
 [Required(ErrorMessage = "必填")]// 必填项目
 [MinLength(1)] // 最小长度
 private string inputValue = "123";

NotifyPropertyChangedRecipients:广播通知

[NotifyPropertyChangedRecipients]
class A : ObservableRecipient
{
    public string Name { get; set; }
    // 广播信息
    protected override void Broadcast<T>(T oldValue, T newValue, string? propertyName)
    {
        base.Broadcast(oldValue, newValue, propertyName);
    }
}

RelayCommand:命令

 [RelayCommand] 
// RelayCommand:自动生成相关内容,可以直接绑定 自动生成name+Command
 private void DoButton()
 {

 }

界面使用:

<Button Content="Btn" Command="{Binding DoButtonCommand}" />

AsyncRelayCommand

异步绑定事件:

public AsyncRelayCommand AsyncButtonCommand { get; set; }
public MainViewModel()
{
    AsyncButtonCommand = new AsyncRelayCommand(AsyncButtonClick);
}
// 异步执行绑定
private Task AsyncButtonClick()
{
 return Task.Run(() => { });
}
// 以上相当于:
private void BtnClick()
{
 Task.Run(() => { });
}

Message相关/ ObservableRecipient

需要继承类:ObservableRecipient,实现接口IRecipient<in TMessage>

在构造函数中,开启消息接收this.IsActive = true;

核心代码如下:

private void BtnClick()
{
 // 触发
 WeakReferenceMessenger.Default.Send<string>("Hello");
}
// 接受
public void Receive(string message)
{
 // message == Hello
}
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值