2017-02-17 3 views
0

У меня есть наблюдаемая коллекция класса, которая реализует как BindableBase, так и IDataErrorInfo. На мой взгляд, у меня есть кнопка, привязка которой ICommand должна выполняться только тогда, когда каждый элемент в наблюдаемой коллекции проверяется. Поскольку один из элементов почти всегда начинает действовать недействительным, кнопка изначально отключена. У меня есть следующий код в моем конструкторе:DelegateCommand в Prism, чей метод canExecuteMethod определяется свойством в ObservableCollection. Как продолжить «Наблюдать» canExecute?

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

Где определяется моя наблюдаемая коллекция следующим образом:

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

И реализация IDataErrorInfo в моем классе Paramters как это:

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> для свойств, но я не уверен, как применить это к свойству внутри класса, который является частью от ObservableCollection.

Спасибо.

ответ

1

В дополнение к ответу @ Брайан Lagunas' вы могли бы обрабатывать PropertyChanged событие для всех элементов в вашей Parameters коллекции и вызвать 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(); 
    } 

    //... 
} 
+0

Спасибо! Ваш метод работал отлично. (Я использовал выражение лямбда PropertyChangedEventHandler, а не метод). – GrantA

1

В этом случае вы не используете ObservesProperty или ObservesCanExcute. Вы должны вручную вызвать StartInspectionCommand.RaiseCanExecuteChanged, когда свойства в вашей коллекции были обновлены.

0

Если есть какие-либо могильщики все еще ищут ответы на этот вопрос. Я нашел другое обходное решение для этой проблемы, поскольку я не мог заставить мой 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(); 
} 

Я не уверен, что недостатки делать это таким образом, если какой-либо, но будет обновляться, если я бежать в любой.

Смежные вопросы