One of the features that WPF has is actually a blast from the past - something that MFC used to have, but was never included in WinForms. This is the concept of Commands. Commands are somewhat like events in that they are based on actions in the user interface, a command can get triggered (just like an event). But unlike regular events like 'click', commands are built in a way that makes it very easy to expose the same functionality at multiple places in an interface, with very little code duplication.
On of the very useful features of commands is the fact that you actually get an automatic form of two way communication between the interface elements and the command they are bound too. This is because a command is made up of two main elements -
Today we are going to take a look at how to use the built in commands that WPF provides (and there are a lot of them). The handy thing about the built in commands is that a number of the standard controls automatically respond to them. Take a look at the XAML code below:
Essentially, what we have here is a set of buttons in one row that operate on the
Because of these commands, there is no actual code behind required - and really, the buttons know virtually nothing about the rich text box. If you grab the xaml and compile and play with it, you might notice something really cool - the buttons even become enabled and disabled appropriately. For instance, if you have nothing selected in the text box, the Copy and Cut buttons will be disabled, but as soon as you select something, the buttons will automatically enable.
The two important properties that are being set on each button are
Ok, now onto the
The only item left in the XAML above that still needs to be explained is what is being done with the
Well, that is all for this introduction to WPF commands. I'll be back soon with a tutorial on how to write and use your own WPF commands - and that is where the real power comes in.
On of the very useful features of commands is the fact that you actually get an automatic form of two way communication between the interface elements and the command they are bound too. This is because a command is made up of two main elements -
Execute
and CanExecute
. So unlike in the regular world of events, when an action becomes unavailable, you can just have the CanExecute
part of the command return false - and everything hooked to that command becomes disabled. Without this, you would have to do any of a number of ugly things to make sure that all user interface elements that perform an action are always correctly enabled or disabled.Today we are going to take a look at how to use the built in commands that WPF provides (and there are a lot of them). The handy thing about the built in commands is that a number of the standard controls automatically respond to them. Take a look at the XAML code below:
<Window x:Class="SimpleTextEditor.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CommandTest" Height="300" Width="318">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="textBoxCommands">
<Setter Property="Content" Value=
"{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
<Setter Property="CommandTarget" Value="{Binding ElementName=textBox}" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button Command="Cut" Style="{StaticResource textBoxCommands}" />
<Button Command="Copy" Style="{StaticResource textBoxCommands}" />
<Button Command="Paste" Style="{StaticResource textBoxCommands}" />
<Button Command="AlignCenter" Style="{StaticResource textBoxCommands}" />
<Button Command="AlignLeft" Style="{StaticResource textBoxCommands}" />
<Button Command="AlignRight" Style="{StaticResource textBoxCommands}" />
<Button Command="Undo" Style="{StaticResource textBoxCommands}" />
</StackPanel>
<RichTextBox Grid.Row="1" Name="textBox"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
</Window>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CommandTest" Height="300" Width="318">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="textBoxCommands">
<Setter Property="Content" Value=
"{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
<Setter Property="CommandTarget" Value="{Binding ElementName=textBox}" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button Command="Cut" Style="{StaticResource textBoxCommands}" />
<Button Command="Copy" Style="{StaticResource textBoxCommands}" />
<Button Command="Paste" Style="{StaticResource textBoxCommands}" />
<Button Command="AlignCenter" Style="{StaticResource textBoxCommands}" />
<Button Command="AlignLeft" Style="{StaticResource textBoxCommands}" />
<Button Command="AlignRight" Style="{StaticResource textBoxCommands}" />
<Button Command="Undo" Style="{StaticResource textBoxCommands}" />
</StackPanel>
<RichTextBox Grid.Row="1" Name="textBox"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
</Window>
RichTextBox
below them. Here is a simple screenshot of what this looks like:The two important properties that are being set on each button are
Command
and CommandTarget
. The Command
property specifies what command should be executed when the button is clicked. This is different for each button, because each button causes a different command to be executed. The Command
property can be written in two forms for built in commands - the short form that you saw above (like Command="Paste"
), or the long form: Command="{x:Static ApplicationCommands.Paste}"
. The short form can only be used for the built in commands, because WPF knows where they are. For the commands used above, Cut
, Copy
, Paste
, and Undo
are all in the ApplicationCommands
class, and AlignCenter
, AlignLeft
, and AlignRight
are all in the EditingCommands
class. There are a a couple of other built in command classes as well: NavigationCommands
, MediaCommands
, and ComponentCommands
.Ok, now onto the
CommandTarget
. The command target specifies what element the command is going to be executed on. In the case of these buttons, the target is always the textBox
, which is why the target is factored out into that textBoxCommands
style in the window resources. If the command target is not set, the command will just bubble up in the application until it hits some parent that watches for that command (if there is no such parent, the command does nothing and in fact will always be disabled). So, for instance, if you somehow place one of these buttons inside the texbox, you wouldn't need to set the target, because the command would bubble up and the textbox would grab it.The only item left in the XAML above that still needs to be explained is what is being done with the
Button
Content
property. Well, every command has a Text
field on it which should contain a readable name for the command, so why not use that as the text on the button instead of explicitly setting the content to something like "Cut"? That is what that binding is doing in the style - it is grabbing the Text
property off of the command attached to the button, and setting that text as the content of the button. Well, that is all for this introduction to WPF commands. I'll be back soon with a tutorial on how to write and use your own WPF commands - and that is where the real power comes in.
0 Comments