Mvvm 在ReactiveUI中提升属性更改的正确方法

Mvvm 在ReactiveUI中提升属性更改的正确方法,mvvm,reactiveui,Mvvm,Reactiveui,有时,我需要为相关属性筹集propertychanged,如下所示: public bool IsValid { get { return _isValid; } set { if (value.Equals(_isValid)) return; _isValid = value; OnPropertyChanged("IsValid"); On

有时,我需要为相关属性筹集propertychanged,如下所示:

public bool IsValid
    {
        get { return _isValid; }
        set
        {
            if (value.Equals(_isValid)) return;
            _isValid = value;
            OnPropertyChanged("IsValid");
            OnPropertyChanged("IsSavable");
        }
    }
public bool IsValid
    {
        get { return _isValid; }
        set
        {
            if (value.Equals(_isValid)) return;
            _isValid = value;
            this.RaisePropertyChanged("IsValid");
            this.RaisePropertyChanged("IsSavable");
        }
    }
我可以这样写:

public bool IsValid
    {
        get { return _isValid; }
        set
        {
            if (value.Equals(_isValid)) return;
            _isValid = value;
            OnPropertyChanged("IsValid");
            OnPropertyChanged("IsSavable");
        }
    }
public bool IsValid
    {
        get { return _isValid; }
        set
        {
            if (value.Equals(_isValid)) return;
            _isValid = value;
            this.RaisePropertyChanged("IsValid");
            this.RaisePropertyChanged("IsSavable");
        }
    }
代码基于Paul的回答:

    public ViewModelBase()
    {
        Validator = new AlwaysTrueValidValidator<ViewModelBase>();
        // logic for IsSavable
        this.WhenAny(x => x.IsValid, x => x.IsDirty, x => x.IsBusy, (valid, dirty, busy) => valid.Value && dirty.Value && busy.Value == false)
            .ToProperty(this, x => x.IsSavable, out _isSavable);
    }

    readonly ObservableAsPropertyHelper<bool> _isSavable;
    public bool IsSavable
    {
        get { return _isSavable.Value; }
    }

    [UsedImplicitly]
    public bool IsValid
    {
        get { return _isValid; }
        set { this.RaiseAndSetIfChanged(ref _isValid, value); }
    }

    public void OnPropertyChanged(string property)
    {
        // ReSharper disable once ExplicitCallerInfoArgument
        this.RaisePropertyChanged(property);
    }
public ViewModelBase()
{
Validator=新的AlwayStrueValidator();
//可分配逻辑
此.WhenAny(x=>x.IsValid,x=>x.IsDirty,x=>x.IsBusy,(有效,脏,忙)=>valid.Value&&dirty.Value&&busy.Value==false)
.ToProperty(this,x=>x.IsSavable,out\u IsSavable);
}
只读ObservablesPropertyHelper可保存;
公共图书馆是可以申请的
{
获取{return\u isSavable.Value;}
}
[正确使用]
公共布尔是有效的
{
获取{return\u isValid;}
设置{this.RaiseAndSetIfChanged(ref_isValid,value);}
}
公共void OnPropertyChanged(字符串属性)
{
//ReSharper禁用一次显式CallerInfo参数
此。RaisePropertyChanged(财产);
}
正如您所看到的,代码更干净,它是所有的get/set,逻辑在一个地方


有更聪明的方法吗?是的

在ReactiveUI中,这样做的愿望意味着你做错了(或者至少,不是用RxUI的方式)。IsSaveable与IsValid相关,您应该在任何时候使用
TopProperty来描述它。也许你可以这样写:

this.WhenAny(x => x.IsValid, x => x.IsChanged, (valid, changed) => valid.Value && changed.Value)
    .ToProperty(this, x => x.IsSavable, out isSavable);

所以属性都应该是哑get/setter,属性的交互逻辑应该在构造函数中设置?是的,它们应该使用RaiseAndSetIfChanged,交互是在构造函数中从ReactiveUI文档中设置的…Property vs ObservableAsPropertyHelper如果要更改值,则应使用一个属性和RaiseAndSetIfChanged