This topic is tended to be an abbreviated version to this Commanding Overview document on MSDN website. If you want to have a fully understanding about it, please click that link and read it thoroughly.
Commanding is an input mechanism in WPF. There are two kinds of input mechanism in WPF which .NET Framework 4.0 supports: mouse click (MouseGesture) and keyboard input (KeyGesture).
Command
Commands are routed. Commands in WPF are created by implementing the ICommand interface. ICommand exposes two methods, Execute, and CanExecute, and an event, CanExecuteChanged. If you set a break point inside of your CanExecute method, you will find the CanExcute method is invoke periodically by the system or .NET Framework to determines whether the command can execute on the current command target.
Command Library
WPF provides a set of predefined routed commands. The command library consists of the following classes: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommands, and the ComponentCommands. These classes provide commands such as Cut, BrowseBack and BrowseForward, Play, Stop, and Pause.
Many of these commands include a set of default input bindings. For example, if you specify that your application handles the copy command, you automatically get the keyboard binding "CTRL+C" You also get bindings for other input devices, such as Tablet PC pen gestures and speech information.
These classes consist only of the RoutedCommand objects and not the implementation logic of the command. The implementation logic is the responsibility of the object on which the command is being executed on.
Command Soureces
A command source is the object which invokes the command. Command sources in WPF generally implement the ICommandSource interface. ICommandSource exposes three properties: Command, CommandTarget, and CommandParameter:
-
Command is the command to execute when the command source is invoked.
-
CommandTarget is the object on which to execute the command. It is worth noting that in WPF the CommandTarget property on ICommandSource is only applicable when the ICommand is a RoutedCommand. If the CommandTarget is set on an ICommandSource and the corresponding command is not a RoutedCommand, the command target is ignored. If the CommandTarget is not set, the element with keyboard focus will be the command target.
-
CommandParameter is a user-defined data type used to pass information to the handlers implementing the command.
The WPF classes that implement ICommandSource are ButtonBase, MenuItem, Hyperlink, and InputBinding. ButtonBase, MenuItem, and Hyperlink invoke a command when they are clicked, and an InputBinding invokes a command when the InputGesture associated with it is performed.
Simple Command Examples:
The following examples show how to set up a MenuItem so that when it is clicked it will invoke the Paste command on a TextBox, assuming the TextBox has keyboard focus.
XAML example:
1: <StackPanel>
2: <Menu>
3: <MenuItem Command="ApplicationCommands.Paste"
4: CommandParameter="ButtonOne"
5: CommandTarget="{Binding ElementName=textBox1}" />
6: </Menu>
7: <TextBox naem="textBox1" />
8: </StackPanel>
C# example:
1:
2: // Creating the UI objects
3: StackPanel mainStackPanel = new StackPanel();
4: TextBox pasteTextBox = new TextBox();
5: Menu stackPanelMenu = new Menu();
6: MenuItem pasteMenuItem = new MenuItem();
7:
8: // Adding objects to the panel and the menu
9: stackPanelMenu.Items.Add(pasteMenuItem);
10: mainStackPanel.Children.Add(stackPanelMenu);
11: mainStackPanel.Children.Add(pasteTextBox);
12:
13: // Setting the command to the Paste command
14: pasteMenuItem.Command = ApplicationCommands.Paste;
15:
16: // Setting the command target to the TextBox
17: pasteMenuItem.CommandTarget = pasteTextBox;
Command Binding
A CommandBinding Binds a RoutedCommand to the event handlers that implement the command. Here are examples of binding a custom RoutedCommand and binding a WPF provides RoutedCommand.
XAML example:
1: <Window x:Class="CustomRoutedCommandSample.MainWindow"
2: ...
3: xmlns:custom="clr-namespace:CustomRoutedCommandSample
4: ... >
5: <Window.CommandBindings>
6: <CommandBinding Command="{x:Static
7: custom:MainWindow.CustomRoutedCommand}"
8: Executed="StartCommand_Executed"
9: CanExecute="StartCommand_CanExecute"/>
10: <CommandBinding Command="MediaCommands.Stop"
11: Executed="StopCommand_Executed"
12: CanExecute="StopCommand_CanExecute"/>
13: </Window.CommandBindings>
14: <Grid>
15: <StackPanel>
16: <Button x:Name="btnPlay" Content="Play"
17: Command="{x:Static
18: custom:MainWindow.CustomRoutedCommand}" />
19: <Button x:Name="btnStop" Content="Stop"
20: Command="MediaCommands.Stop" />
21: </StackPanel>
22: </Grid>
23: </Window>
Remember to add a public static RoutedCommand class in your C# code:
1: // Add a custom routed command
2: public static RoutedCommand CustomRoutedCommand = new RoutedCommand();
3:
4: // Implememt your business logic in the following methods
5: private void StartCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
6: {
7: // Your code here
8: e.CanExecute = true; // Specify your condition here
9: e.Handled = true;
10: }
11:
12: private void StartCommand_Executed(object sender, ExecutedRoutedEventArgs e)
13: {
14: // Your code here
15: e.Handled = true;
16: }
17:
18: private void StopCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
19: {
20: // Your code here
21: e.CanExecute = true; // Specify your condition here
22: e.Handled = true;
23: }
24:
25: private void StopCommand_Executed(object sender, ExecutedRoutedEventArgs e)
26: {
27: // Your code here
28: e.Handled = true;
29: }
Key Binding
You can use XAML
1: <Window.InputBindings>
2: <KeyBinding Key="B"
3: Modifiers="Control"
4: Command="ApplicationCommands.Open" />
5: </Window.InputBindings>
Tow ways to use in C# code
1: // Create a KeyBinding between a KeyGesture and a RoutedCommand.
2: KeyGesture StartKeyGesture = new KeyGesture(
3: Key.P,
4: ModifierKeys.Control);
5: KeyBinding StartCmdKeyBinding = new KeyBinding(
6: MediaCommands.Play,
7: StartKeyGesture);
8: this.InputBindings.Add(StartCmdKeyBinding);
9:
10: // Add a KeyGesture to the InputGestureCollection of a RoutedCommand.
11: KeyGesture StopKeyGesture = new KeyGesture(
12: Key.S,
13: ModifierKeys.Control);
14: MediaCommands.Stop.InputGestures.Add(StopKeyGesture);
No comments:
Post a Comment