C# - 如何处理模型的属性更改以在ViewModel

时间:2018-03-12 12:37:23

标签: c# .net xaml mvvm binding

根据MVVM架构,我们有一个视图,其中2 DataGrids的数据相关,视图模型的ObservableCollection<Model>

模型具有布尔属性,基于该属性是网格启用/禁用之一。一切正常,当我更改选定的Model时,网格无法使用。但是,当我更改属性时,不会调用客户属性Notify的{​​{1}}(当我选中/取消选中第一个网格中的复选框时,我需要在属性上调用IsSelectedModelChecked Notify)。

问:我如何在模型的属性更改中调用属性更改?

我已经检查了几个问题,但没有人回答我的问题。我想从头脑中提出一些想法,但我不知道。感谢

&lt;不必要的代码省略&gt;

XAML:

IsSelectedModelChecked

型号:

<DataGrid
      ItemsSource="{Binding Models}"
      SelectedItem="{Binding SelectedModel}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name"
                 Binding="{Binding Name}"/>
        <DataGridCheckBoxColumn Header="Check"
                 Binding="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}">
    </DataGrid.Columns>
</DataGrid>

<DataGrid
      IsEnabled="{Binding IsSelectedModelChecked}"/>

查看 - 型号:

public class Model : Microsoft.VisualStudio.PlatformUI.ObservableObject
{
    private string mName = @"<Name>";
    public string Name
    {
        get { return mName; }
        set { SetProperty(ref mName, value); }
    }

    private bool mIsChecked = false;
    public bool IsChecked
    {
        get { return mIsChecked; }
        set { SetProperty(ref mIsChecked, value); }
    }
}

2 个答案:

答案 0 :(得分:1)

您必须倾听SelectedModel的{​​{1}}事件。

PropertyChanged

此外,如果模型实例的寿命比视图模型长,则需要注意泄漏视图模型实例。

答案 1 :(得分:0)

这是Haukinger答案的延伸。他提到内存泄漏的问题,当ViewModel实例被销毁时可能会发生,但模型将存在并且处理程序仍将附加到事件。

在这种情况下,WPF实现了一个名为Weak Event Pattern的东西,它允许处理这种情况。对于属性更改,存在实现此类弱事件模式的现有PropertyChangedEventManager。代码应写为:

public Model SelectedModel
{
    get { return mSelectedModel; }
    set
    {
        if (mSelectedModel != null)
            PropertyChangedEventManager.RemoveHandler(mSelectedModel, OnSelectedModelPropertyChanged, "");

        SetProperty(ref mSelectedModel, value);

        if (mSelectedModel != null)
            PropertyChangedEventManager.AddHandler(mSelectedModel, OnSelectedModelPropertyChanged, "");

        NotifyPropertyChanged(nameof(IsSelectedModelChecked));
    }
}

private void OnSelectedModelPropertyChanged( object sender, PropertyChangedEventArgs args)
{
    if (args.PropertyName == nameof(Model.IsChecked))
        NotifyPropertyChanged(nameof(IsSelectedModelChecked));
}