ReactiveUI - 如何共享 属性?

ReactiveUI - How to share a Property?

我在两个派生 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 需要一个实例来执行,我们如何才能有一个绑定在两个不同视图中的 属性 并共享其绑定??

考虑使用 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 重复相同的过程。

您需要考虑的另一个注意事项是您可能想要处理 ToProperty() 的订阅。在上面的示例中,我只是完成了一个简单的 Dispose,您还可以使用 WhenActivate 的机制。