属性可视化
给一个属性添加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;
}
}
}
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" />
传递普通的值
点击按钮,把信息传入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;
}
}
}