MVVM ViewModel级联属性



我有一个具有属性a, B, C和D的视图模型,其中D是a, B和C的和,因此无论何时这些变化,我都希望D得到更新。我知道我可以通过观察A, B, C上的PropertyChanged事件,然后设置D的值来做到这一点,像这样:

public MyViewModel()
{
    this.PropertyChanged += ViewModelPropertyChanged;
}
private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // Track changes to update sum
    if (e.PropertyName == "A" || e.PropertyName == "B" || e.PropertyName == "C")
    {
        D = A + B + C;
    }
}

但我想知道是否有更优雅或更自动化的存在?

更新此属性以添加属性的示例。我使用的框架封装了:is different的逻辑,并引发了property changed事件。

    private int _A;
    public int A
    {
        get { return _A; }
        set { RaiseAndSetIfChanged(ref _A, value); }
    }

更新#2:有没有人有一个例子,这可能是如何实现使用ReactiveUI?

与其在你的ViewModelPropertyChanged中做实际的数学计算,不如这样做

private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // Track changes to update sum
    if (e.PropertyName == "A" || e.PropertyName == "B" || e.PropertyName == "C")
    {
        OnPropertyChanged("D");
    }
}

然后对属性本身进行计算

public int D
{
    get
    {
        return A + B + C;
    }
} 

或者你可以这样做(这是我喜欢的,详见下面的注释)

public int A
{
    get { return a; }
    set
    {
        if (value == a) return;
        a = value;
        OnPropertyChanged("A");
        OnPropertyChanged("D");
    }
}
public int B
{
    get { return b; }
    set
    {
        if (value == b) return;
        b = value;
        OnPropertyChanged("B");
        OnPropertyChanged("D");
    }
}

等等

public int D
{
    get
    {
        return A + B + C;
    }
} 

你可以考虑在其他属性的'set'中运行一些代码:

private int a;
public int A
{
    get { return a; }
    set
    {
        a= value;
        D = A + B + C
    }
}

如果你认为这样更优雅,你可以自己决定,这只是一个建议。

我会像下面这样使用ReactiveUI Observable作为属性助手:

public class ViewModel : ReactiveObject
{
    private int a = 2;
    public int A
    {
        get { return a; }
        private set { this.RaiseAndSetIfChanged(ref a, value); }
    }
    private int b = -1;
    public int B
    {
        get { return b; }
        private set { this.RaiseAndSetIfChanged(ref b, value); }
    }
    private int c = 5;
    public int C
    {
        get { return c; }
        private set { this.RaiseAndSetIfChanged(ref c, value); }
    }
    private ObservableAsPropertyHelper<int> dHelper;
    public int D => dHelper.Value;
    public ViewModel()
    {
        dHelper = this.WhenAnyValue(
            vm => vm.a,
            vm => vm.b,
            vm => vm.c,
            (a, b, c) => a + b + c)
            .ToProperty(this, nameof(D));
    }
}

最新更新