Ottenere oggetti non UI per rispondere ai collegamenti dei comandi WPF
Domanda
Ho una classe ViewModel alla quale voglio rispondere al comando Refresh integrato che viene attivato da un pulsante ma non sono sicuro di come dichiarare il CommandTarget.
In breve, il mio codice è come di seguito
Il costruttore ViewModel e i gestori di eventi CanExecute ed Executed -
public ViewModel()
{
CommandBinding binding = new CommandBinding(NavigationCommands.Refresh, CommandHandler);
binding.CanExecute += new CanExecuteRoutedEventHandler(binding_CanExecute);
binding.Executed += new ExecutedRoutedEventHandler(binding_Executed);
CommandManager.RegisterClassCommandBinding(typeof(ViewModel), binding);
}
void binding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Debug.Print("Refreshing...");
}
void binding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
Il markup è -
<Button Command="Refresh">refresh</Button>
Ora, ho provato a impostare CommandTarget su questo pulsante su {Binding Source = {StaticResource ViewModel}}
ma ho un runtime che dice Impossibile convertire il valore nell'attributo 'CommandTarget' all'oggetto di tipo "System.Windows.IInputElement"
.
Sono nuovo ai comandi, quindi è del tutto possibile che qui mi sbagli di tutto. Qualsiasi aiuto sarebbe apprezzato.
Soluzione
RoutedCommand
se MVVM non si mescolano. I RoutedCommand
sono legati all'albero visivo e fanno affidamento sulla raccolta CommandBindings
di WPF. Dovresti implementare le tue classi ICommand
che funzionano con il modello MVVM. Dai un'occhiata a Implementazioni di Prism per cominciare.
Nei miei progetti MVVM, ho un paio di implementazioni di comandi:
-
DelegateCommand
. Chiamate fornite ai delegati per determinare se il comando può essere eseguito ed eseguire il comando. -
ActiveAwareCommand
. Funziona insieme a un'interfaccia (IActiveAware
) e invia esecuzioni di comandi all'elemento attualmente attivo. Molteplici implementazioni attive attive si registrano con il comando e il comando instrada automaticamente le chiamateCanExecute
/Execute
verso l'elemento attualmente attivo.