2015-05-02 10 views
5

Po pierwsze, mówię, że jestem na samym początku WPF i wzorca MVVM.Jak korzystać z metody CanExecute z ICommand na WPF

Podczas testowania niestandardowych poleceń zastanawiałem się, jak korzystać z metody CanExecute Methode z interfejsu ICommand.

W moim przykładzie mam SaveCommand, które tylko mogę włączyć, gdy obiekt można zapisać. XAML kod mojego Savebutton wygląda następująco:

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

Jest to kod mojego ratowania klasy:

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

Obiekt zapisać w ViewModel wygląda następująco:

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

Ta konstrukcja nie działa. Przycisk nie włącza się, gdy właściwość isSaveable jest prawdziwa.

Odpowiedz

4

Zamiast definiować własną implementację ICommand, należy użyć RelayCommand.

W poniższym przykładowym kodzie zapis Button jest włączony, gdy użytkownik wpisze coś w polu TextBox.

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> 

Kod za:

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(); 
     } 
    } 
} 
Powiązane problemy