如何使用ReactiveUI连接模型并查看模型属性



我正在使用带有ReactiveUI的MVVM。我在模型中有一个属性,我想在UI中显示并编辑它。使用ReactiveUI有什么简单的方法可以做到这一点吗?应满足以下特性:

  • 模型属性实现INotifyPropertyChanged
  • 可以从视图模型或从模型更改模型属性
  • 模型内部的更新可以在任何线程上进行
  • 视图模型的更新应该使用节流阀,这样就不是每次击键都会成为模型更新
  • 应用程序只能使用UI或命令行运行,并且代码也应该可以在单元测试和集成测试中运行
  • 使用UI时,需要在UI线程上引发ViewModel的PropertyChanged事件
  • 油门在任一运行模式下都不能阻塞
  • 代码应该是健壮的,即不存在导致死锁或恢复到旧值的风险

我不知何故认为这将是一个如何将视图模型连接到模型的标准案例,但还没有成功实现,而且如果没有为一个看似简单的任务编写大量代码,我真的无法找到任何方法来实现它。

非工作实现的示例代码:

public interface IModel : INotifyPropertyChanged
{
string MyProperty { get; set; }
}
public class SomeViewModel : ReactiveObject
{
private readonly IModel model;
public SomeViewModel(IModel model)
{
MyProperty = String.Empty;
this.model = model;
var inputThrottleTime = TimeSpan.FromMilliseconds(500);
var scheduler = RxApp.MainThreadScheduler is AvaloniaScheduler
? RxApp.MainThreadScheduler
: RxApp.TaskpoolScheduler;
// This doesn't work. If updates are made in the model inputThrottleTime apart, the old value might be reassigned to the model.
// And also, WhenAnyValue shouldn't be used to listen on properties that might be updated on background threads according to ReactiveUI devs.
this.WhenAnyValue(x => x.model.MyProperty).ObserveOn(scheduler).Subscribe(p => MyProperty = p);
this.WhenAnyValue(x => x.MyProperty).Skip(1).Throttle(inputThrottleTime, scheduler)
.Subscribe(p => model.MyProperty = p);
}

[Reactive] public string MyProperty { get; set; } 
}

您可以使用数据绑定。选择视图中的控件组件(xaml(。之后,您将为该视图提供一个数据上下文。为控件提供数据上下文和项源有不同的方法。你可以在xaml文件中这样做:

<Window.DataContext>
<vm:ViewModels.MainWindowViewModel />
</Window.DataContext>
<TextBlock Text="{Binding Name}"/>

之后,您可以访问变量。此变量必须具有get-set属性,并且您可以在此处使用ReactiveUI。

public string Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}

我在阿瓦隆尼亚用过这个。有关更多信息,您可以查看以下内容:https://docs.avaloniaui.net/docs/data-binding

最新更新