ObservableObject 是通过实现 INotifyPropertyChanged 和 INotifyPropertyChanging 接口可观察的对象的基类。
1,ObservableObject
包含以下主要功能:
- 它提供了对
INotifyPropertyChanged
和INotifyPropertyChanging
的基本实现,从而公开PropertyChanged
和PropertyChanging
事件。 - 它提供了一系列
SetProperty
方法,这些方法可用于轻松设置继承自ObservableObject
的类型中的属性值,并自动引发相应的事件。 - 它提供了
SetPropertyAndNotifyOnCompletion
方法,该方法与SetProperty
类似,但能够设置Task
属性并在分配的任务完成后自动引发通知事件。 - 它公开了
OnPropertyChanged
和OnPropertyChanging
方法,这些方法可在派生类型中重写,以自定义引发通知事件的方式。
2,ObservableObject在WPF中的应用
步骤 1: 创建Model
Model代表应用的数据模型。在这个示例中,我们创建一个简单的Person
模型。
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
步骤 2: 创建ViewModel
ViewModel充当View和Model之间的中介。它从Model中获取数据,并以一种易于View显示的方式提供这些数据。此外,它还处理用户的命令和请求,从而影响Model或其他应用部分的状态。
使用CommunityToolkit.Mvvm
,ObservableObject
类使属性通知更简单。
using CommunityToolkit.Mvvm.ComponentModel;
public partial class ObservableExampleViewModel: ObservableObject
{
private string _message;
public string Message
{
get { return _message; }
set
{
if (_message != value)
{
_message = value;
OnPropertyChanged();
}
}
}
[ObservableProperty]
private string name;
[ObservableProperty]
private int age;
public ObservableExampleViewModel() {
Person _person = new Person{ Age = 30,Name ="wangwu"};
Name = _person.Name;
Age = _person.Age;
}
}
步骤 3: 在XAML View中使用ViewModel
在WPF中,你通常会在XAML中绑定ViewModel作为DataContext。以下是如何在MainWindow的XAML布局中设置ViewModel
实例的示例。
<StackPanel>
<TextBox Width="150" Height="30" Margin="0 10 0 10" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBox Width="150" Height="30" Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBlock Text="{Binding Name}"></TextBlock>
</StackPanel>
像是效果
当运行应用程序时,将看到两个文本框显示了ViewModel
中的Name
和Age
属性的值。在文本框中更改这些值时,由于我们使用了ObservableProperty
特性,所以ViewModel
中的相应属性会自动更新,如果有其他视图元素绑定了这些属性,它们也会相应更新。
如上在WPF应用程序中使用MVVM模式和ObservableObject
来实现视图和ViewModel之间的数据绑定。
如果不用CommunityToolkit.Mvvm,需要自己创建ObservableObject基类以实现
INotifyPropertyChanged,代码如下:
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ViewModel继承此基类即可。
[ObservableProperty]
private string age;
等同于
public int Age
{
get => _person.Age;
set
{
if (value != _person.Age)
{
_person.Age = value;
OnPropertyChanged();
}
}
}
ObservableProperty 类型是一种允许从带批注字段生成可观察属性的特性。 其用途是显著减少定义可观察属性所需的样本量。
注意:必须将class 声明为partial。
3.Task属性应用
在 CommunityToolkit.Mvvm
的早期版本中,NotifyTask
的功能是通过 NotifyTaskCompletion
类提供的。从 CommunityToolkit.Mvvm
版本 7.0 开始,这个类已经被 TaskNotifier
和 ObservableObject
中的 SetPropertyAndNotifyOnCompletion
方法替代,用于更简洁地处理异步操作和结果通知。SetPropertyAndNotifyOnCompletion
绑定与普通绑定方式相同
具体实例如下:
步骤 1: 创建ViewModel
public partial class TaskViewModel : ObservableObject
{
// TaskNotifier属性用于UI绑定
[ObservableProperty]
private string data;
public IAsyncRelayCommand LoadDataCommand { get; }
public TaskViewModel()
{
LoadDataCommand = new AsyncRelayCommand(ExecuteLoadDataAsync);
}
private async Task ExecuteLoadDataAsync()
{
// 模拟异步数据加载
await Task.Delay(2000).ContinueWith(t => Data = "Data loaded successfully!");
// 使用SetPropertyAndNotifyOnCompletion来更新Data属性并通知UI
//SetPropertyAndNotifyOnCompletion(ref data, loadDataTask);
}
}
步骤 2: 更新MainWindow.xaml以使用ViewModel
<StackPanel Margin="10">
<Button Content="Load Data" Command="{Binding LoadDataCommand}" />
<TextBlock Text="{Binding Data}" Margin="5"/>
</StackPanel>
结果:
点击load Data按钮 等待两秒显示结果如上。