#343 – Associating Multiple Controls with the Same Command
July 15, 2011 2 Comments
One benefit of using commands in WPF, as opposed to writing event handlers, is that it’s easier to link multiple controls to a single command. With commands, you can create a single command object, bind it to a method, and then associate the command with more than one control by setting the Command property of each control.
In the example below, we associate the ApplicationCommands.Open command with both a Button and a MenuItem.
<Window.ContextMenu> <ContextMenu> <MenuItem Header="Open" Command="ApplicationCommands.Open"/> </ContextMenu> </Window.ContextMenu> <StackPanel> <Button Content="Open" Command="ApplicationCommands.Open" HorizontalAlignment="Center" /> </StackPanel>
In the code-behind, we still only have to create a single CommandBinding instance.
public MainWindow() { this.InitializeComponent(); CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, Open_Executed, Open_CanExecute)); } public void Open_Executed(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("Open file code goes here"); } public void Open_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; // Can we open file? }
Hey I really love this site. Best training source I’ve found so far.
I’m looking at this run in the debugger and it seems like it’s running Open_CanExecute()
many, many times… Is this normal? I was also surprised to see that it ran Open_CanExecute()
first.
Looking forward to hearing from you : )
Thanks KG,
When I run this example, I don’t see _CanExecute getting called a lot. It’s pretty quiet until I start interacting with the app and then it calls it occasionally. The documentation is a little fuzzy on how often CanExecute will get called, but it’s essentially–any time that something changes which could potentially change the answer to the CanExecute. In my example, the CommandManager has no idea that I’m always going to return true, so it continues to call CanExecute occasionally to find out if the command is still valid. This makes sense–if it just called the method once and then something changed in your class that would have caused the result of CanExecute to change, you’d want it to have called you as soon as possible so that it can discover that the answer has changed.
Knowing that CanExecute can be called as often as the CommandManager likes (or needs to), it’s important to make this function as lightweight as possible. Ideally it would just return a boolean that you’ve already calculated, as a result of changing whatever conditions feed into the logic.
–Sean