如何让 Prism 的 DelegateCommand 观察 child view-model 的 属性?

How can I make Prism's DelegateCommand observe a child view-model's property?

我的“parent”view-model (AnalyzeVm) 有一个 child view-model (ScanVm) 表示可以保存到磁盘。我想给 parent 一个命令 (SaveCmd),只有当 ScanVm.IsDirty 属性 为真时才启用。

我已经在各处使用 DelegateCommand 及其 ObservesProperty 功能,因此我尝试将其用于此目的。但在这种情况下,我无法获得 ObservesProperty 表达式来触发对 CanExecute.

的调用

这里的区别(与我使用的所有其他地方 ObservesProperty 工作正常)是我正在监视 child object 的 属性。不是我自己的

我需要了解为什么这不起作用。我认为这是正确的做法。

这是两个视图模型(为清晰起见,已删除)

// Parent view-model.  Derives from a class that implements INotifyPropertyChanged.

public class AnalyzeVm : BaseViewModel
{
    private ScanVm _scan;

    public AnalyzeVm(ScanVm scan)
    {
        _scan = scan;

        // Set up the command.  Try to make it monitor a property of the ScanVm
        // object instead of one of our own.

        SaveScanCmd = new DelegateCommand(
            () => { _scan.Save() }                 // execute -- saves the scan
            () => { return _scan.IsDirty; })       // only valid when scan is dirty
            .ObservesProperty(() => scan.IsDirty); // So observe IsDirty property

        // Now just as a sanity check, add a handler for that property changing
        // to the PropertyChangedEventManager and log when it does.

        PropertyChangedEventManager.AddHandler(
            scan, 
            (_, _) => Debug.WriteLine("IsDirty changed"), 
            nameof(ScanContext.IsDirty));
    }

    public ICommand SaveScanCmd { get; }

    // other code...
}

// ScanVm class.  

public class ScanVm : BaseViewModel
{
    private bool _isDirty;
    public bool IsDirty
    { 
        get => _isDirty;
        set => SetProperty(ref _isDirty, value);  // Raises PropertyChanged event
    }
    public void Save()
    {
        // Code here to save the ScanVm
       
        IsDirty = false;  // No longer dirty
    }
    // ... other code
}

我确定 IsDirty 属性 正在正确更改并触发事件。我确认了很多次。当我观察自己的 class' 属性时,我已经成功地使用了 Observes 属性。例如,我要将 SaveCmd 移到 ScanVm class 本身——这样 属性 表达式就观察到了 ScanVm' s own 属性,那么就可以正常工作了。我在我的代码中到处都这样做。

这是我试图观察另一个 object 的 属性 的唯一地方。这样做有效吗?如果是这样,我做错了什么?

ObservesProperty 主要作用于包含对象的属性

public bool IsDirty {...}

...ObservesProperty( () => IsDirty );

加嵌套属性

public ScanVM Child {...}

...ObservesProperty( () => Child.IsDirty );

它只是不观察任何给定实例的属性,因为它从包含对象开始查找(在本例中为 AnalyzeVm)。