我有三个 C# 类 A、B 和 C,其中
- A 是一个视图模型
- B 是一个模型
- C 是一个状态类(包含有关设备的一些状态信息,例如 IsConnected)
它们连接在一起,使得 B 具有 C 类型的属性。C 包含近 30 个表示设备状态的属性。我决定让 B 通过 INotifyPropertyChanged 更新 A,现在我正在寻找一种方法让 A 在 C 中的属性发生更改时得到通知。
实现这一目标的最简单方法是什么?
更新:
这段代码可以解决问题。
class Gun : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public GunState GunState { get; private set; }
public Gun()
{
GunState = new GunState();
GunState.PropertyChanged += GunStateOnPropertyChanged;
}
private void GunStateOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
NotifyPropertyChanged(propertyChangedEventArgs.PropertyName);
}
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
class GunState : INotifyPropertyChanged
{
private bool _isLoaded;
public event PropertyChangedEventHandler PropertyChanged;
public bool IsLoaded
{
get { return _isLoaded; }
private set
{
if (_isLoaded != value)
{
_isLoaded = value;
NotifyPropertyChanged("IsLoaded");
}
}
}
public void SimulateLoadGun(bool isLoaded)
{
IsLoaded = isLoaded;
}
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
class GunViewModel : INotifyPropertyChanged
{
private readonly Gun _gun;
public GunViewModel()
{
_gun = new Gun();
_gun.PropertyChanged += OnGunOnPropertyChanged;
}
public string IsLoaded
{
get { return _gun.GunState.IsLoaded ? "Gun is loaded!" : "Gun is not loaded."; }
}
private void OnGunOnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
NotifyPropertyChanged(args.PropertyName);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public void LoadGun()
{
_gun.GunState.SimulateLoadGun(!_gun.GunState.IsLoaded);
}
}
XAML:
<Window x:Class="ModelViewModelInteraction.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:ModelViewModelInteraction"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:GunViewModel x:Name="_model" />
</Window.DataContext>
<Grid>
<Label Content="{Binding IsLoaded}" Margin="0,0,313,262" />
<Button Content="Load gun" Click="Button_Click_1" Margin="73,83,283,59" />
</Grid>
</Window>
XAML.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
_viewModel = new GunViewModel();
DataContext = _viewModel;
}
private GunViewModel _viewModel;
private void Button_Click_1(object sender, RoutedEventArgs e)
{
_viewModel.LoadGun();
}
}