如何从作为模型中的属性公开的类引用更新ViewModel

时间:2013-04-11 18:26:14

标签: c# mvvm

我有三个C#类A,B和C,其中

  • A是ViewModel
  • B是模型
  • C是状态类(包含有关设备的一些状态信息,例如IsConnected)

连接它们使得B具有类型C的属性.C包含表示设备状态的近30个属性。 我决定让B通过INotifyPropertyChanged更新A,现在我正在寻找一种方法,当C中的属性发生变化时,A会被告知。

实现这一目标的最简单方法是什么?

更新:

这段代码可以解决问题。

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

1 个答案:

答案 0 :(得分:1)

我会关注Law of Demeter; A不应该知道C中发生了什么。相反,当A中的相关属性发生变化时,B应该关注来自C的通知。

例如,您的模型B可以拥有自己的IsConnected属性,您可以继续使用INotifyPropertyChanged机制。