#1,083 – Setting CommandBindings in XAML

You can configure command bindings in code-behind, adding a CommandBinding object to a top-level window’s CommandBindings collection, as follows:

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                Executed_Open, CanExecute_Open));
        }

You can set this command binding up in XAML, rather than in code-behind.  Below is an example of doing the same binding in XAML.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Commands" Width="320" Height="220">

    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Open"
                        Executed="Executed_Open"
                        CanExecute="CanExecute_Open"/>
    </Window.CommandBindings>

    <StackPanel>
        <Button Content="Open" Command="ApplicationCommands.Open"
                Margin="10" Padding="10,3"
                HorizontalAlignment="Center" />
        <CheckBox Content="Can Open" IsChecked="{Binding CanOpenIsChecked}"
                  Margin="10"/>
    </StackPanel>
</Window>

This assumes that you’ve defined the following methods in code-behind:

        public void Executed_Open(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("Executing the Open command");
        }

        public void CanExecute_Open(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = CanOpenIsChecked;
        }

#1,082 – Adding CommandBindings to Individual UI Elements

Before using a routed command, you need to associated a particular command object with code for the Execute and CanExecute methods.  You do this by creating a CommandBinding object that binds the command to the code.  You then typically add that CommandBinding to the CommandBindings collection for the top-level window.

If you want to use the same command object, but bind it to different executable code for different UI elements, you can instead add the CommandBinding objects to the CommandBindings for individual elements.  In the code below, we create two different bindings for the ApplicationCommands.Open command.

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            btnA.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                (sender, e) => { MessageBox.Show("Executing the Open command (version A)"); },
                (sender, e) => { e.CanExecute = CanOpenIsChecked; }));

            btnB.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                (sender, e) => { MessageBox.Show("Executing the Open command (version B)"); },
                (sender, e) => { e.CanExecute = CanOpenIsChecked; }));
        }

1082-001
1082-002

#1,081 – Adding CommandBinding to Top-Level CommandBindings

In the example below, we bind the ApplicationCommands.Open command to some custom code by adding a CommandBinding instance to the top-level window’s CommandBindings property.

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                (sender, e) => { MessageBox.Show("Executing the Open command"); },
                (sender, e) => { e.CanExecute = CanOpenIsChecked; }));
        }

We can now bind the Command property of any UI element under the top-level window to the ApplicationCommands.Open command.  Below, we bind two different buttons to the Open command.  Clicking on either button will result in execution of the same lambda expression.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Commands" Width="320" Height="220">

    <StackPanel>
        <Button Content="Open A" Command="ApplicationCommands.Open"
                Margin="10" Padding="10,3"
                HorizontalAlignment="Center" />
        <Button Content="Open B" Command="ApplicationCommands.Open"
                Margin="10" Padding="10,3"
                HorizontalAlignment="Center" />
        <CheckBox Content="Can Open" IsChecked="{Binding CanOpenIsChecked}"
                  Margin="10"/>
    </StackPanel>
</Window>

1081-001

#1,080 – Command Text for Preexisting Commands Is Automatically Localized

If you use any of the preexisting RoutedUICommand objects in your application, the Text property of the command is automatically localized to match the language of the operating system that you’re running on.

Assume that you wire a Button up to an Open command:

        <Button Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"
                Command="ApplicationCommands.Open" />

If we run the application, the button text is in English.

1080-001

If we run the application on a French version of Windows, the text on the button will be localized.  Assuming that we have the proper language pack installed, we can also just override the CurrentUICulture of the current thread.

    public partial class App : Application
    {
        public App()
        {
           Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
        }
    }

Now when we run the application, the word “Open” is translated to French.
1080-002

#1,079 – Executing a Command Programmatically

You normally bind the Command property of a user interface element to a routed command to have the command automatically executed when the user interacts with the user interface element.

You can also execute commands programmatically by calling their Execute method.  Note that the command will do nothing if CanExecute is returning false.

        <Button Content="Do Something" Click="Button_Click"
                Margin="10" HorizontalAlignment="Center"/>
        <CheckBox Content="Can Open" IsChecked="{Binding CanOpenIsChecked}"
                  Margin="10"/>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                (sender, e) => { MessageBox.Show("Executing the Open command"); },
                (sender, e) => { e.CanExecute = CanOpenIsChecked; }));
        }

        // INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        private void RaisePropertyChanged(string propName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

        public bool CanOpenIsChecked { get; set; }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // Execute command programmatically
            if (ApplicationCommands.Open.CanExecute(null, null))
                ApplicationCommands.Open.Execute(null, null);
            else
                MessageBox.Show("No no no!");
        }
    }

1079-001
 

#1,078 – Defining a Command Binding Using Lambda Expressions

Recall that commands in WPF are objects that you bind UI elements to and that are in turn bound to code for executing the command and for knowing whether a command can be executed.

Below is an example that sets up a command binding using lambda expressions.

    <Window.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Open" Command="ApplicationCommands.Open"/>
        </ContextMenu>
    </Window.ContextMenu>

    <StackPanel>
        <Button Content="Open" Command="ApplicationCommands.Open"
                Margin="10" HorizontalAlignment="Center" />
        <CheckBox Content="Can Open" IsChecked="{Binding CanOpenIsChecked}"
                  Margin="10"/>
    </StackPanel>

We set up the command binding in the window’s constructor.

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                (sender, e) => { MessageBox.Show("Executing the Open command"); },
                (sender, e) => { e.CanExecute = CanOpenIsChecked; }));
        }

        // INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        private void RaisePropertyChanged(string propName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

        public bool CanOpenIsChecked { get; set; }
    }

1078-001
1078-002

#1,077 – Checking for Single Modifer vs. Multiple Modifier Keys

In keypress events, you can check to see if the user is also holding down one of the modifier keys (Ctrl, Alt, Shift, or Windows key).  You do this by checking the KeyEventArgs.KeyboardDevice.Modifiers property.

You sometimes want to check to see if one and only one modifier key is being held down (e.g. Ctrl key without Alt, Shift, or Windows).  You do this by checking to see if the Modifiers property is equal to one of the ModifierKeys enumerated values.

            if ((e.Key == Key.G) &&
                (e.KeyboardDevice.Modifiers == ModifierKeys.Control))
                MessageBox.Show("Ctrl+G detected, NO Alt/Shift/Windows");

You may also want to check to see if the control key is being pressed, either alone or in conjunction with one of the other modifier keys.  You do this by using a mask.

            if ((e.Key == Key.G) &&
                ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control))
                MessageBox.Show("Ctrl+G or Ctrl+Alt+G, Ctrl+Alt+Windows+G, etc.");