2017-02-17 3 views
0

Ich habe eine beobachtbare Sammlung einer Klasse, die sowohl BindableBase als auch IDataErrorInfo implementiert. Aus meiner Sicht habe ich eine Schaltfläche, deren ICommand Bindung sollte nur ausführbar sein, wenn jedes Element in der beobachtbaren Sammlung validiert ist. Da eines der Elemente fast immer ungültig wird, ist die Schaltfläche ursprünglich deaktiviert. Ich habe den folgenden Code in meinem Konstruktor:DelegateCommand in Prism, dessen canExecuteMethod durch eine Eigenschaft in einer ObservableCollection bestimmt wird. Wie kann ich weiter "Beobachten" canExecute?

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

Wo meine beobachtbaren Sammlung ist wie folgt definiert:

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

Und die Umsetzung von IDataErrorInfo in meiner Paramter Klasse ist wie folgt:

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; 
     } 
    } 

In welcher Syntax wird canExecuteMethod neu ausgewertet, wenn der Benutzer gültige Werte in die verschiedenen Parameter eingibt? (Oder, in der Tat, verursacht derzeit gültigen diejenigen ungültig zu machen.)

Ich verstehe, wie ObservesCanExecute und ObservesProperty<T> für Eigenschaften selbst zu verwenden, aber ich bin mir nicht sicher, wie man das auf eine Eigenschaft innerhalb einer Klasse, die Teil ist der ObservableCollection.

Danke.

Antwort

1

Neben @ Brian Lagunas' Antwort könnten Sie die PropertyChanged Ereignis für alle Artikel im Parameters Sammlung handhaben und die RaiseCanExecuteChanged Methode aufrufen, wenn jede Eigenschaft des Elements geändert wird, zB:

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

Vielen Dank! Deine Methode hat perfekt funktioniert. (Ich habe jedoch einen Lambda-PropertyChangedEventHandler-Ausdruck anstelle einer Methode verwendet.) – GrantA

1

Sie verwenden ObservesProperty oder ObservesCanExcute nicht in diesem Szenario. Sie müssen StartInspectionCommand.RaiseCanExecuteChanged manuell aufrufen, wenn die Eigenschaften in Ihrer Sammlung aktualisiert wurden.

0

Wenn es welche gibt Totengräber suchen immer noch nach Antworten auf diese Frage Ich habe eine andere Problemumgehung für dieses Problem gefunden, da ich meine ObservableCollection nicht dazu bringen konnte, das CollectionChanged-Ereignis auszulösen.

Nach der Sammlung bevöl manuell iteriert I und stellen Sie die für jedes Element Property, wie unten:

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

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

Ich bin nicht sicher, was die Nachteile sind es auf diese Art und Weise zu tun, wenn überhaupt, aber aktualisiert, wenn ich laufe in irgendeinen.

Verwandte Themen