ReactiveUI-如何共享属性?

时间:2018-07-27 18:09:36

标签: uwp reactiveui rx.net

我遇到了一个问题,即两个派生的ViewModel之间共享一个属性:

public abstract class MyBaseViewModel : ViewModelBase
{
    private string _sharedProperty;
    public string SharedProperty
    {
        get => _sharedProperty;
        set => this.RaiseAndSetIfChanged(ref _sharedProperty, value);
    }
}

public abstract class ViewModelA : MyBaseViewModel
{

}

public abstract class ViewModelB : MyBaseViewModel
{

}

public sealed partial class FirstPage : IViewFor<ViewModelA>
{
    this.Bind(ViewModel,
        vm => vm.SharedProperty,
        view => view.MycontrolA.Text)
    .DisposeWith(disposable);
}

public sealed partial class SecondPage : IViewFor<ViewModelB>
{
    this.Bind(ViewModel,
        vm => vm.SharedProperty,
        view => view.MycontrolB.Text)
    .DisposeWith(disposable);
}

当我从 SecondPage 更新 SharedProperty 时, FirstPage 上的绑定没有更新。现在,显然每个ViewModel都有该属性的实例,因为它不是 static 。由于 RaiseAndSetIfChanged 需要一个实例来执行,我们如何才能拥有一个在两个不同视图中绑定并共享其绑定的属性?

1 个答案:

答案 0 :(得分:2)

考虑使用DependencyInjection和某种已注册常量值来存储两个对象之间的注册。然后使用ObservableAsPropertyHelper来使您的属性保持最新。

在您的Splat DI中注册您的

    private static void RegisterDynamic(IMutableDependencyResolver resolver)
    {
         resolver.RegisterConstant<IMyDataType>(new MyDataType());
    }

然后可以在ViewModels构造函数中完成

public class ViewModelA : IDisposable
{    
    private readonly ObservableAsPropertyHelper<string> sharedProperty;
    private readonly IMyDataType dataType;

    public ViewModelA(IMyDataType dataType = null)
    {
        this.dataType = dataType ?? Locator.Current.GetService<IMyDataType>();
        this.sharedProperty = dataType.WhenAnyValue(x => x.SharedProperty).ToProperty(this, x => x.SharedProperty);
    }

    public string SharedProperty => this.sharedProperty.Value;

    public void Dispose() => this.sharedProperty?.Dispose();
}

然后,您可以对ViewModelB重复相同的过程。

您还需要考虑的另一项考虑是,您可能希望处置Subscription for ToProperty()。在上面的示例中,我刚刚完成了一个简单的Dispose,还有一些可以使用WhenActivate的机制。