Prism 中的 DelegateCommand,其 canExecuteMethod 由 ObservableCollection 中的 属性 确定。如何继续 "Observe" canExecute?

DelegateCommand in Prism whose canExecuteMethod is determined by a property in an ObservableCollection. How do I continue to "Observe" canExecute?

我有一个 class 的可观察集合,它实现了 BindableBaseIDataErrorInfo。在我看来,我有一个按钮,其 ICommand 绑定只有在验证可观察集合中的每个元素时才应可执行。由于其中一个元素几乎总是在开始时无效,因此该按钮最初是禁用的。我的构造函数中有以下代码:

this.StartInspectionCommand = new DelegateCommand(this.StartInspection, () => this.Parameters.All(p => string.IsNullOrEmpty(p["Value"])))

我的可观察集合定义如下:

public ObservableCollection<Parameter> Parameters { get; } = new ObservableCollection<Parameter>();

而我的参数class中IDataErrorInfo的实现是这样的:

public string this[string columnName]
    {
        get
        {
            if (columnName != "Value" // Only validate value column
                || string.IsNullOrEmpty(this._validationExpression) // No validation means all values including null are valid
                || (this.Value != null && Regex.IsMatch(this.Value, this._validationExpression))) // No null allowed when validating
            {
                return "";  // No error
            }

            return this._validationMessage;
        }
    }

当用户在各种参数中输入有效值时,使 canExecuteMethod 重新计算的语法是什么? (或者,就此而言,导致当前有效的无效。)

我了解如何将 ObservesCanExecuteObservesProperty<T> 用于属性本身,但我不确定如何将其应用于 class 内部的 属性那是 ObservableCollection.

的一部分

谢谢。

在这种情况下,您不使用 ObservesProperty 或 ObservesCanExcute。当 collection 中的属性更新后,您必须手动调用 StartInspectionCommand.RaiseCanExecuteChanged。

除了@Brian Lagunas 的回答之外,您还可以处理 Parameters 集合中所有项目的 PropertyChanged 事件,并在任何项目 [=16= 时调用 RaiseCanExecuteChanged 方法] 已更改,例如:

public class ViewModel
{
    public ViewModel()
    {
        this.StartInspectionCommand = new DelegateCommand(this.StartInspection, () => this.Parameters.All(p => string.IsNullOrEmpty(p["Value"])))
        this.Parameters.CollectionChanged += Parameters_CollectionChanged;
    }

    public ObservableCollection<Parameter> Parameters { get; } = new ObservableCollection<Parameter>();

    private void Parameters_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (object parameter in e.NewItems)
            {
                (parameter as INotifyPropertyChanged).PropertyChanged
                    += new PropertyChangedEventHandler(item_PropertyChanged);
            }
        }

        if (e.OldItems != null)
        {
            foreach (object parameter in e.OldItems)
            {
                (parameter as INotifyPropertyChanged).PropertyChanged
                    -= new PropertyChangedEventHandler(item_PropertyChanged);
            }
        }
    }

    private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        StartInspectionCommand.RaiseCanExecuteChanged();
    }

    //...
}

如果有任何掘墓人仍在寻找这个问题的答案,我已经找到了解决这个问题的不同方法,因为我无法让我的 ObservableCollection 触发 CollectionChanged 事件。

填充集合后,我手动迭代并为每个项目设置了 propertychanged,如下所示:

OrdersToConfirm = new ObservableCollection<mConfirmedQuote>(_quoteService.GetOrdersToBeConfirmed());
OrdersToConfirm.ToList().ForEach(x => { x.PropertyChanged += item_PropertyChanged; });

private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
     ConfirmCommand.RaiseCanExecuteChanged();
}

我不确定这样做有什么缺点,如果有的话,但如果我 运行 变成任何缺点,我会更新。