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

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;}}
}

相关文章:

  • LeRobot 项目部署运行逻辑(六)——visualize_dataset_html.py/visualize_dataset.py
  • Google的A2A和MCP什么关系
  • 低成本自动化改造技术锚点深度解析
  • 在js中大量接口调用并发批量请求处理器
  • @PostConstruct @PreDestroy
  • 流式渲染 Streaming SSR
  • 深入解析C++核心特性:运算符重载、继承、多态与抽象类
  • 第三节第二部分:Static修饰方法应用场景
  • 学习黑客搜索技巧
  • 解决应用程序在JAR包中运行时无法读取类路径下文件的问题
  • SSH(安全外壳协议)
  • 软件安全(二)优化shellcode
  • FreeRTOS如何实现100%的硬实时性?
  • 龙虎榜——20250509
  • 编译原理实验 之 语法分析程序自动生成工具Yacc实验
  • nvidia-smi 和 nvcc -V 作用分别是什么?
  • 算法设计与分析复习代码(hnust)
  • LVGL源码学习之渲染、更新过程(3)---绘制和刷写
  • 操作系统导论——第26章 并发:介绍
  • 68、微服务保姆教程(十一)微服务的监控与可观测性
  • 华泰柏瑞基金总经理韩勇因工作调整卸任,董事长贾波代为履职
  • 冯德莱恩:欧美贸易谈判前不会前往美国会见特朗普
  • 第一集|《刑警的日子》很生活,《执法者们》有班味
  • 少年中国之少年的形塑
  • 北京:下调个人住房公积金贷款利率
  • 习近平抵达莫斯科伏努科沃专机机场发表书面讲话(全文)