2010-09-22 11 views
5

in meinem WPF UI, verwende ich RoutedCommands, die ich über den folgenden Code in meiner XAML verweisen:WPF Benutzerdefinierte ICommand Implementierung und das CanExecuteChanged Ereignis

Command="viewModel:MessageListViewModel.DeleteMessagesCommand" 

Ich mag nicht diese statische Link zu meinem Viewmodel-Klasse ich denke, dies ist eine Syntax wie die folgenden

Command="{Binding DeleteMessagesCommand}" 

Nachdem man erstellt eine benutzerdefinierte ICommand Implementierung wie das Erstellen und verwenden Sie nicht so schön ist, merke ich, einen großen Nachteil von dem, was ich getan habe: RoutedCommands die Befehlsmanager nutzen und (in gewisser Weise ist das für mich völlig undurchsichtig) Feuer Das CommandManager.RequerySuggested-Ereignis, sodass die CanExecute-Methode automatisch erneut angefordert wird. Wie für meine benutzerdefinierte Implementierung wird CanExecute nur einmal beim Start und nie wieder danach ausgelöst.

Hat jemand eine elegante Lösung dafür?

Antwort

8

implementieren einfach das CanExecuteChanged Ereignis wie folgt:

public event EventHandler CanExecuteChanged 
{ 
    add { CommandManager.RequerySuggested += value; } 
    remove { CommandManager.RequerySuggested -= value; } 
} 

Wenn Sie den Befehl an eine Steuer zuweisen, abonniert es das CanExecuteChanged Ereignis. Wenn Sie es an das Ereignis CommandManager.RequerySuggested "umleiten", wird die Steuerung benachrichtigt, sobald CommandManager.RequerySuggested ausgelöst wird.

+0

Dank einem Haufen für diese große und prägnante Antwort! Klappt wunderbar. Wissen Sie, wann und warum RequerySuggested ausgelöst wird? –

+1

Nicht genau, aber ich scheint ziemlich oft passieren ... –

+0

OK, vielen Dank noch einmal! –

0

Ich bevorzuge die DelegateCommand-Implementierung von Prism für Viewmodel-Bindung (http://msdn.microsoft.com/en-us/library/ff654132.aspx). Sie können CanExecute() bei jedem Aufruf des Befehls aufrufen, indem Sie RaiseCanExecuteChanged aufrufen.

einfaches Anwendungsbeispiel:

public class ViewModel 
{ 
    public ViewModel() 
    { 
     Command = new DelegateCommand<object>(x => CommandAction(), x => CanCommandAction()); 
    } 

    bool state; 

    public void ChangeState(bool value) 
    { 
     state = value; 
     Command.RaiseCanExecuteChanged(); 
    } 

    public DelegateCommand<object> Command {get; private set;} 

    private void CommandAction() 
    { 
     //do smthn 
    } 

    private bool CanCommandAction() { return true == state; } 
} 

//and binding as usual 
Command="{Binding Command}" 
+0

Danke für die Idee, aber - wie wir erfahren haben - "mit großer Kraft kommt große Verantwortung" ... –

+0

Sorry, gedrückt Enter zu früh. Was ich meine ist: Während es mir die Chance gibt, zwingt es mich dazu, es zu tun, um benachrichtigt zu werden. –

Verwandte Themen