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 的机制。
我在两个派生 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 的机制。