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 的可观察集合,它实现了 BindableBase
和 IDataErrorInfo
。在我看来,我有一个按钮,其 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 重新计算的语法是什么? (或者,就此而言,导致当前有效的无效。)
我了解如何将 ObservesCanExecute
和 ObservesProperty<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();
}
我不确定这样做有什么缺点,如果有的话,但如果我 运行 变成任何缺点,我会更新。
我有一个 class 的可观察集合,它实现了 BindableBase
和 IDataErrorInfo
。在我看来,我有一个按钮,其 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 重新计算的语法是什么? (或者,就此而言,导致当前有效的无效。)
我了解如何将 ObservesCanExecute
和 ObservesProperty<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();
}
我不确定这样做有什么缺点,如果有的话,但如果我 运行 变成任何缺点,我会更新。