2015-05-02 9 views
5

Zuerst verwenden i gleich am Anfang von WPF und dem MVVM Pattern ist zu sagen.Wie die CanExecute Methode von ICommand auf WPF

Während einiger benutzerdefinierten Befehle versuchen, ich frage mich, wie die CanExecute Methode aus der ICommand-Schnittstelle zu verwenden.

In meinem Beispiel hat ich eine SaveCommand, die ich nur das, was ermöglichen, wenn das Objekt speicherbar ist. Der XAML-Code meiner Savebutton sieht wie folgt aus:

<Button Content="Save" Command="{Binding SaveCommand, Mode=TwoWay}" /> 

Dies ist der Code meiner speichern Klasse ist:

class Save : ICommand 
{ 
    public MainWindowViewModel viewModel { get; set; } 

    public Save(MainWindowViewModel viewModel) 
    { 
     this.viewModel = viewModel; 
    } 

    public bool CanExecute(object parameter) 
    { 

     if (viewModel.IsSaveable == false) 
      return false; 
     return true; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     viewModel.Save(); 
    } 
} 

Die speichern Eigenschaft im Ansichtsmodell sieht wie folgt aus:

public ICommand SaveCommand 
    { 
     get 
     { 
      saveCommand = new Save(this); 
      return saveCommand; 
     } 
     set 
     { 
      saveCommand = value; 
     } 
    } 

Dieses Konstrukt hat nicht funktioniert. Die Schaltfläche aktiviert nicht seine selbst wenn isSaveable wahr ist.

Antwort

4

Statt eine eigene Implementierung von ICommand zu definieren, verwenden Sie einen RelayCommand.

In dem folgenden Beispielcode ist das Speichern Button aktiviert, wenn der Benutzer etwas in TextBox eingibt.

XAML:

<Window x:Class="RelayCommandDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel HorizontalAlignment="Center"> 
     <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Margin="5" Width="120"/> 
     <Button Content="Save" Command="{Binding SaveCommand}" Margin="3"/> 
    </StackPanel> 
</Window> 

-Code hinter:

using System; 
using System.Windows; 
using System.Windows.Input; 

namespace RelayCommandDemo 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      DataContext = new VM(); 
     } 
    } 
    public class VM 
    { 
     public String Name { get; set; } 

     private ICommand _SaveCommand; 

     public ICommand SaveCommand 
     { 
      get { return _SaveCommand; } 
     } 

     public VM() 
     { 
      _SaveCommand = new RelayCommand(SaveCommand_Execute, SaveCommand_CanExecute); 
     } 

     public void SaveCommand_Execute() 
     { 
      MessageBox.Show("Save Called"); 
     } 

     public bool SaveCommand_CanExecute() 
     { 
      if (string.IsNullOrEmpty(Name)) 
       return false; 
      else 
       return true; 
     } 
    } 

    public class RelayCommand : ICommand 
    { 
     public event EventHandler CanExecuteChanged 
     { 
      add { CommandManager.RequerySuggested += value; } 
      remove { CommandManager.RequerySuggested -= value; } 
     } 
     private Action methodToExecute; 
     private Func<bool> canExecuteEvaluator; 
     public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator) 
     { 
      this.methodToExecute = methodToExecute; 
      this.canExecuteEvaluator = canExecuteEvaluator; 
     } 
     public RelayCommand(Action methodToExecute) 
      : this(methodToExecute, null) 
     { 
     } 
     public bool CanExecute(object parameter) 
     { 
      if (this.canExecuteEvaluator == null) 
      { 
       return true; 
      } 
      else 
      { 
       bool result = this.canExecuteEvaluator.Invoke(); 
       return result; 
      } 
     } 
     public void Execute(object parameter) 
     { 
      this.methodToExecute.Invoke(); 
     } 
    } 
}