【发布时间】:2022-01-02 02:10:37
【问题描述】:
设置
让我们假设以下内容。我们有一个用于 WPF 应用程序的以下 理论 视图模型类:
public MyViewModel
{
public MyViewModel()
{
// Condition under which this command may be executed is:
// this.ActiveDocument.Highlighting.Type == Highlighting.Xml &&
// !this.ActiveDocument.IsReadOnly &&
// (this.License.Kind == LicenseKind.Full || this.License.TrialDay < 30)
MyCommand = new Command(obj => DoSomething());
}
public ICommand MyCommand { get; }
// (all other required properties)
}
另外:
- 当前类正确实现
INotifyPropertyChanged - 成员访问链中的所有类都正确实现
INotifyPropertyChanged(例如,可从ActiveDocument属性访问的文档视图模型) -
ActiveDocument可能是null。ActiveDocument.Highlighting也可以为空。
问题
我希望仅在满足评论中的条件时启用该命令。
不带 RX 的选项
我写了my own library 来处理这种情况。解决方案是:
public MyViewModel
{
private readonly Condition commandAvailableCondition;
public MyViewModel()
{
commandAvailableCondition = new LambdaCondition(this,
vm => m.ActiveDocument.Highlighting.Type == Highlighting.Xml &&
!vm.ActiveDocument.IsReadOnly &&
(vm.License.Kind == LicenseKind.Full || vm.License.TrialDay < 30),
false);
MyCommand = new AppCommand(obj => DoSomething(), commandAvailableCondition);
}
public ICommand MyCommand { get; }
// (all other required properties)
}
或者 - 如果您希望代码更具可读性,以便可以重用部分条件 - 就像这样:
public MyViewModel
{
private readonly Condition commandAvailableCondition;
public MyViewModel()
{
var highlightingIsXml = new LambdaCondition(this,
vm => vm.ActiveDocument.Highlighting.Type == Highlighting.Xml,
false);
var documentIsReadonly = new LambdaCondition(this,
vm => vm.ActiveDocument.IsReadOnly,
false);
var appIsLicensed = new LambdaCondition(this,
vm => vm.License.Kind == LicenseKind.Full || this.License.TrialDay < 30,
false);
commandAvailableCondition = highlightingIsXml & !documentIsReadonly & appIsLicensed;
MyCommand = new AppCommand(obj => DoSomething(), commandAvailableCondition);
}
public ICommand MyCommand { get; }
// (all other required properties)
}
我的库(或者更准确地说,LambdaCondition 类)所做的是:
- 它跟踪所有实现
INotifyPropertyChanged的实例并处理更改(例如,当ActiveDocument更改或ActiveDocument.Highlighting更改或ActiveDocument.Highlighting.Type更改等时) - 它会跟踪可能的
nulls,在这种情况下它将返回默认值(在这种情况下为false) - 它会自动报告命令可用性的更改(但仅更改),以便在需要时刷新 UI。
问题
如何在 C# 中使用 System.Reactive 实现上述场景?是否可以轻松地做到这一点,同时保持关于INotifyPropertyChanged 的所有要求、途中的空值和默认值?您可以在需要时做出任何合理的假设。
【问题讨论】:
标签: c# wpf mvvm system.reactive