当前位置: 首页 > web >正文

CommunityToolkit.Mvvm详解

属性可视化

给一个属性添加ObservableProperty就可以可视化了

[ObservableProperty]
private string currentNameInfo;[ObservableProperty]
private string currentClassInfo;[ObservableProperty]
private string currentPhoneInfo;

xaml中只需要绑定大写的属性就可以了

<StackPanel Orientation="Horizontal"Grid.ColumnSpan="2"Grid.Row="1"><TextBlock Width="200"Height="40"FontSize="30"Text="{Binding CurrentNameInfo,TargetNullValue=null}"HorizontalAlignment="Center" /><TextBlock Width="200"Height="40"FontSize="30"Text="{Binding CurrentClassInfo,TargetNullValue=null}"HorizontalAlignment="Center" /><TextBlock Grid.Row="1"Width="200"Height="40"FontSize="30"Text="{Binding CurrentPhoneInfo,TargetNullValue=null}"HorizontalAlignment="Center" />
</StackPanel>

命令

可以用RelayCommand来简便的指定命令

[RelayCommand]
void AddButtonClick()
{Student student = new Student(NameProperty, ClassProperty, PhoneProperty);WeakReferenceMessenger.Default.Send(new ValueChangedMessage<Student>(student));
}

xaml中只需要绑定方法名加Command就可以了

<Button Grid.Row="3"Content="存入列表"Height="40"IsEnabled="{Binding CanAllow}"Command="{Binding AddButtonClickCommand}"Width="100" />

Message

传递自定义类

两个ViewModel之间传递自定义类

1.定义一个自定义的类

public record StringMessage(string message);

2.注册自定义类

通过WeakReferenceMessenger来注册StringMessage

public partial class ReciverUCViewModel:ObservableObject
{[ObservableProperty]private string? recivetxt;public ReciverUCViewModel(){WeakReferenceMessenger.Default.Register<StringMessage>(this, Receive);}private void Receive(object recipient, StringMessage message){Recivetxt = message.message;}
}

3.发送消息

public partial class SenderUCViewModel : ObservableObject
{//[ObservableProperty]//private string? sendertxt="null";private string? sendertxt;public string Sendertxt{get { return sendertxt; }set{if (SetProperty(ref sendertxt, value)){WeakReferenceMessenger.Default.Send(new StringMessage(value));}}}
}

传递PropertyChangedMessage

接收

public partial class ReciverUCViewModel:ObservableObject
{[ObservableProperty]private string? recivetxt;public ReciverUCViewModel(){WeakReferenceMessenger.Default.Register<PropertyChangedMessage<string>>(this,Receive);}private void Receive(object recipient, PropertyChangedMessage<string> message){Recivetxt = message.NewValue;}
}

可以用IRecipient来优化简便代码

public partial class ReciverUCViewModel : ObservableObject, IRecipient<PropertyChangedMessage<string>>
{[ObservableProperty]private string? recivetxt;public ReciverUCViewModel(){WeakReferenceMessenger.Default.Register(this);}public void Receive(PropertyChangedMessage<string> message){Recivetxt = message.NewValue;}
}

发送

public partial class SenderUCViewModel : ObservableObject
{//[ObservableProperty]//private string? sendertxt="null";private string? sendertxt;public string Sendertxt{get { return sendertxt; }set{if (SetProperty(ref sendertxt, value)){WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string>(this,nameof(Sendertxt),default,value));}}}
}

传递RequestMessage

发送

public partial class SenderUCViewModel : ObservableObject
{//[ObservableProperty]//private string? sendertxt="null";private string? sendertxt;public string Sendertxt{get { return sendertxt; }set{if (SetProperty(ref sendertxt, value)){var res=WeakReferenceMessenger.Default.Send(new RequestMessage<string>());sendertxt = res.Response;}}}
}

接收

public partial class ReciverUCViewModel : ObservableObject,IRecipient<RequestMessage<string>>
{[ObservableProperty]private string? recivetxt;public ReciverUCViewModel(){WeakReferenceMessenger.Default.Register(this);}public void Receive(RequestMessage<string> message){recivetxt = message.ToString();message.Reply("hello");}}

简化

ObservableRecipient

可以替代ObservableObject,还能简化注册功能,设置属性IsActive=true就可以免注册

IRecipient

可以直接指明,要接收的类型

public partial class ReciverUCViewModel : ObservableRecipient,IRecipient<PropertyChangedMessage<string>>
{[ObservableProperty]private string? recivetxt;public ReciverUCViewModel(){//WeakReferenceMessenger.Default.Register(this);this.IsActive = true;}public void Receive(PropertyChangedMessage<string> message){Recivetxt = message.NewValue;}
}

心得

对于发送的相同类型的message,可以通过属性的名称来区分,分别处理

发送

public partial class FormUCViewModel:ObservableRecipient
{private string nameProperty;public string NameProperty{get { return nameProperty; }set {if (SetProperty(ref nameProperty, value)){WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string>(this, nameof(NameProperty), default, value));}}}private string classProperty;public string ClassProperty{get { return classProperty; }set {if (SetProperty(ref classProperty, value)){WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string>(this, nameof(ClassProperty), default, value));}}}private string phoneProperty;public string PhoneProperty{get { return phoneProperty; }set {if (SetProperty(ref phoneProperty, value)){WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string>(this, nameof(PhoneProperty), default, value));}}}}

接收

public partial class MainWindowViewModel:ObservableRecipient,IRecipient<PropertyChangedMessage<string>>
{[ObservableProperty]private string currentNameInfo;[ObservableProperty]private string currentClassInfo;[ObservableProperty]private string currentPhoneInfo;public MainWindowViewModel(){this.IsActive = true;}public void Receive(PropertyChangedMessage<string> message){// 根据消息的属性名称更新相应的属性switch (message.PropertyName){case nameof(FormUCViewModel.NameProperty):CurrentNameInfo = message.NewValue;break;case nameof(FormUCViewModel.ClassProperty):CurrentClassInfo = message.NewValue;break;case nameof(FormUCViewModel.PhoneProperty):CurrentPhoneInfo = message.NewValue;break;}}
}

功能展示

传递变化的属性

输入框代码

属性变化,底下的TextBlock也会跟着变化

ObservableProperty可以添加可视化属性,让前端绑定

NotifyPropertyChangedRecipients可以通知订阅了的类,属性变化

public partial class FormUCViewModel:ObservableRecipient
{//现代化写法[ObservableProperty][NotifyPropertyChangedRecipients]private string nameProperty;//现代化写法[ObservableProperty][NotifyPropertyChangedRecipients]private string classProperty;//老式写法private string phoneProperty;public string PhoneProperty{get { return phoneProperty; }set {if (SetProperty(ref phoneProperty, value)){WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string>(this, nameof(PhoneProperty), default, value));}}}}

显示的TextBlock代码

属性变化接收到不同的message,可以用message.PropertyName来区分接收的属性

public partial class MainWindowViewModel:ObservableRecipient,IRecipient<PropertyChangedMessage<string>>
{[ObservableProperty]private string currentNameInfo;[ObservableProperty]private string currentClassInfo;[ObservableProperty]private string currentPhoneInfo;public MainWindowViewModel(){this.IsActive = true;}public void Receive(PropertyChangedMessage<string> message){// 根据消息的属性名称更新相应的属性switch (message.PropertyName){case nameof(FormUCViewModel.NameProperty):CurrentNameInfo = message.NewValue;break;case nameof(FormUCViewModel.ClassProperty):CurrentClassInfo = message.NewValue;break;case nameof(FormUCViewModel.PhoneProperty):CurrentPhoneInfo = message.NewValue;break;}}
}

image-20250509213207417

ToggleButton用NotifyPropertyChangedRecipients来通知订阅方属性变化了

[ObservableProperty]
[NotifyPropertyChangedRecipients]
private bool isAdd;

xaml

<ToggleButton IsChecked="{Binding IsAdd}"Grid.Row="1"Margin="5,8"HorizontalAlignment="Center"Style="{StaticResource ToggleButtonSwitch}"hc:VisualElement.HighlightBrush="{DynamicResource DangerBrush}" />

Receive接收到了数据要用(message.PropertyName来判断一下,以防接收到别的乱七八糟的数据(必须要弄,这个报错搞死我了

public partial class FormUCViewModel:ObservableRecipient,IRecipient<PropertyChangedMessage<bool>>
{public FormUCViewModel(){IsActive = true;}[ObservableProperty]private bool canAllow;public void Receive(PropertyChangedMessage<bool> message){if (message.PropertyName == nameof(ListUCViewModel.IsAdd)){CanAllow = message.NewValue;}   }}

xaml

<Button Grid.Row="3"Content="存入列表"Height="40"IsEnabled="{Binding CanAllow}"Command="{Binding AddButtonClickCommand}"Width="100" />

image-20250509154736779

传递普通的值

点击按钮,把信息传入listbox

表单代码

public partial class FormUCViewModel:ObservableRecipient
{[ObservableProperty][NotifyPropertyChangedRecipients]private string nameProperty;[ObservableProperty][NotifyPropertyChangedRecipients]private string classProperty;private string phoneProperty;public string PhoneProperty{get { return phoneProperty; }set {if (SetProperty(ref phoneProperty, value)){WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string>(this, nameof(PhoneProperty), default, value));}}}[RelayCommand]void AddButtonClick(){Student student = new Student(NameProperty, ClassProperty, PhoneProperty);WeakReferenceMessenger.Default.Send(new ValueChangedMessage<Student>(student));}}

列表代码

public class ListUCViewModel: ObservableRecipient,IRecipient<ValueChangedMessage<Student>>
{public ListUCViewModel(){lists.Add(new Student("张三", "三班", "123123123"));lists.Add(new Student("李四", "四班", "534343434"));lists.Add(new Student("王五", "六班", "876453534"));lists.Add(new Student("赵六", "二班", "123645634"));IsActive = true;}public ObservableCollection<Student> lists { get; set; } = new ObservableCollection<Student>();public void Receive(ValueChangedMessage<Student> message){lists.Add(message.Value);}
}

依赖注入

安装包

Install-Package Microsoft.Extensions.Hosting
Install-Package Microsoft.Extensions.DependencyInjection

编写App.xaml.cs

public partial class App : Application
{public IHost _host;public App(){_host = Host.CreateDefaultBuilder().ConfigureServices((context, services) =>{services.AddTransient<FormUCViewModel>();services.AddTransient<ListUCViewModel>();services.AddTransient<MainWindowViewModel>();services.AddTransient<ReciverUCViewModel>();services.AddTransient<SenderUCViewModel>();services.AddTransient<HelloServe>();}).Build();}protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);var mainWindow = new MainWindow();var mainViewModel = _host.Services.GetRequiredService<MainWindowViewModel>();mainWindow.DataContext = mainViewModel;mainWindow.Show();}protected override void OnExit(ExitEventArgs e){base.OnExit(e);_host.Dispose();}
}

veiw界面更改数据上下文的引用方式

public partial class ListUC : UserControl
{public ListUC(){InitializeComponent();//this.DataContext=new ListUCViewModel();//修改为依赖注入的方式var app = Application.Current as App;if (app != null){var viewModel = app._host.Services.GetRequiredService<ListUCViewModel>();this.DataContext = viewModel;}}
}
http://www.xdnf.cn/news/4922.html

相关文章:

  • 前端面试每日三题 - Day 29
  • JavaScript性能优化实战,从理论到落地的全面指南
  • 阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
  • webpack代理天地图瓦片
  • 【C++设计模式之Template Method Pattern】
  • mysql 已经初始化好,但是用 dbeaver 连接报错:Public Key Retrieval is not allowed
  • 2025数字孪生技术全景洞察:从工业革命到智慧城市的跨越式发展
  • Vue项目---懒加载的应用
  • Redhat 系统详解
  • 在linux系统中,没有网络如何生成流量以使得wireshark能捕获到流量
  • 数组和切片的区别
  • C#字段、属性、索引器、常量
  • 快速开发-基于gin的中间件web项目开发
  • Mac 3大好用的复制粘贴管理工具对比
  • mac 电脑如何打开剪切板
  • Vue3 官方宣布淘汰 Axios,拥抱Alova.js
  • 【Java基础】——JVM
  • 边缘计算:技术概念与应用详解
  • C# 的异步任务中, 如何暂停, 继续,停止任务
  • 使用oracle goldengate同步postgresql到postgresql
  • 虚拟 DOM 与 Diff 算法
  • spark缓存-persist
  • allure生成测试报告(搭配Pytest、allure-pytest)
  • 【高并发】Celery + Redis异步任务队列方案提高OCR任务时的并发
  • Missashe高数强化学习笔记(随时更新)
  • [Windows] 能同时打开多个图片的图像游览器JWSEE v2.0
  • 霸王茶姬微信小程序自动化签到系统完整实现解析
  • 大模型应用开发之模型架构
  • vue3 ts 写一个滑动选择的日期选择器组件
  • 在Mac M1/M2上使用Hugging Face Transformers进行中文文本分类(完整指南)