MVVM 在视图模型之间同步属性

问题描述 投票:0回答:1

想象一下这种情况: 有视图模型 ViewModelA 和 ViewModelB。这两个模型都是值的数据源(事实来源),我们可以将其称为“选定的”。两个视图模型上都有一个“Selected”属性。 “选定的属性”是可通知的属性(它调用 OnPropertyChanged 事件)。当 ViewModelA 更新“选定”值时,ViewModelB 就会收到有关此更改的通知,反之亦然。

我目前的解决方案: 两个视图模型彼此共享引用(ViewModelA 具有对 ViewModelB 的引用,反之亦然)。当 Selected 属性设置为新值(OnPropertyChanged 被调用)时,该属性也会在另一侧设置。

陷阱: 很明显我当前的解决方案有什么问题:它创建了设置属性的无限循环(ViewModelA 设置值 -> ViewModelA 通知 ViewModelB -> ViewModelB 设置值 -> ViewModelB 通知 ViewModelA -> ViewModelA 设置值 -> ...)。我的解决方案之所以有效,是因为当更改的发起者收到有关更改(最初进行的更改)的通知时,SetProperty 方法不会调用 OnPropertyChanged,因为值是相同的。但是,如果旧的和新的比较评估(由于某种原因)不正确,则存在不定式循环的风险。

问题:如何安全地同步两个视图模型之间的值?

c# .net wpf mvvm .net-4.8
1个回答
0
投票

只要不涉及不精确的值计算,您的比较值解决方案就应该有效。另一种可能性是使用

bool isUpdating
来防止循环。但我更喜欢的解决方案是使用在两个视图模型之间共享的单独对象。

类似:

public class MyProp<T> : INotifyPropertyChanged
{
    private T value;

    public T Value
    {
        get => value;
        set => SetField(ref this.value, value);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.