#1,199 – Complete WPF Command Example
February 4, 2017 4 Comments
Below is a cheat sheet for creating a custom command in WPF.
Use a static property to expose a command object from the ViewModel or code-behind. RoutedUICommand allows for associating control text with the command itself.
private static RoutedUICommand _pressMeCommand = new RoutedUICommand("Press Me", "PressMe", typeof(MainWindow)); public static RoutedUICommand PressMeCommand { get { return _pressMeCommand; } }
Add command handlers (in code-behind or ViewModel).
private void PressMe_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = CowboyCanTalk; } private void PressMe_Executed(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("Howdy howdy I'm a cowboy"); }
Bind the command to its handlers, done here in XAML for a window.
<Window.CommandBindings> <CommandBinding Command="local:MainWindow.PressMeCommand" CanExecute="PressMe_CanExecute" Executed="PressMe_Executed"/> </Window.CommandBindings>
Wire a button up to the command. Note use of command’s Text property for the button’s Content (text).
<Button Command="local:MainWindow.PressMeCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
We can also wire up the command to other GUI elements, e.g. a menu item in a context menu. The menu item’s text is set up automatically.
<Window.ContextMenu> <ContextMenu> <MenuItem Command="{x:Static local:MainWindow.PressMeCommand}" /> </ContextMenu> </Window.ContextMenu>
Pingback: Dew Drop - February 6, 2017 (#2415) - Morning Dew
When naming commands (re: both the identifier & the string arg), is there a standard or best practice? i.e.
// 1. doesn’t use a suffix on the identifier, no string literals
Commit = new RoutedCommand(nameof(Commit), …);
// 2. follows DependencyProperty style (ex: TextProperty & “Text”) but uses a string literal
CommitCommand = new RoutedCommand(“Commit”, …);
// 3. incorrect option? uses both identifier suffix & `nameof` so we end up with an undesirable name
CommitCommand = new RoutedCommand(nameof(CommitCommand), …);
I’d say #1 would be the no-brainer if not for WPF’s convention of adding suffixes on identifiers (like TextProperty or ValueChangedEvent).
I guess the difference here is that commands don’t represent 1 piece of a 2-part setup the way that dependency properties & routed events do.
I think that it’s completely up to you. I would probably go with your option #2.
Why can’t I add the event handlers in ViewModel code, only code-behind option works 😦
Is it something in CommandBinding in XAML which needs to hange to do it?