#349 – Predefined Command Objects, Part II

When you associate a button or menu item to a command object by setting its Command property, you typically associate the control with a preexisting command object.  You can also create your own command, e.g. an instance of a RoutedUICommand.

The preexisting commands listed below are all static properties, pointing to instances of a RoutedUICommand.

  • In NavigationCommands
    • BrowseBack
    • BrowseForward
    • BrowseHome
    • BrowseStop
    • DecreaseZoom
    • Favorites
    • FirstPage
    • GoToPage
    • IncreaseZoom
    • LastPage
    • NavigateJournal
    • NextPage
    • PreviousPage
    • Refresh
    • Search
    • Zoom
  • In EditingCommands
    • AlignCenter
    • AlignJustify
    • AlignLeft
    • AlignRight
    • Backspace
    • CorrectSpellingError
    • DecreaseFontSize
    • DecreaseIndentation
    • Delete
    • DeleteNextWord
    • DeletePreviousWord
    • EnterLineBreak
    • EnterParagraphBreak
    • IgnoreSpellingError
    • IncreaseFontSize
    • IncreaseIndentation
    • MoveDownByLine
    • MoveDownByPage
    • MoveDownByParagraph
    • MoveLeftByCharacter
    • MoveLeftByWord
    • MoveRightByCharacter
    • MoveRightByWord
    • MoveToDocumentEnd
    • MoveToDocumentStart
    • MoveToLineEnd
    • MoveToLineStart
    • MoveUpByLine
    • MoveUpByPage
    • MoveUpByParagraph
    • SelectDownByLine
    • SelectDownByPage
    • SelectDownByParagraph
    • SelectLeftByCharacter
    • SelectLeftByWord
    • SelectToDocumentEnd
    • SelectToDocumentStart
    • SelectToLineEnd
    • SelectToLineStart
    • SelectUpByLine
    • SelectUpByPage
    • SelectUpByParagraph
    • TabBackward
    • TabForward
    • ToggleBold
    • ToggleBullets
    • ToggleInsert
    • ToggleItalic
    • ToggleNumbering
    • ToggleSubscript
    • ToggleSuperscript
    • ToggleUnderline

#348 – Predefined Command Objects, Part I

When you associate a button or menu item to a command object by setting its Command property, you typically associate the control with a preexisting command object.  You can also create your own command, e.g. an instance of a RoutedUICommand.

The preexisting commands listed below are all static properties, pointing to instances of a RoutedUICommand.

  • In ApplicationCommands
    • CancelPrint
    • Close
    • ContextMenu
    • Copy
    • CorrectionList
    • Cut
    • Delete
    • Find
    • Help
    • New
    • Open
    • Paste
    • Print
    • PrintPreview
    • Properties
    • Redo
    • Replace
    • Save
    • SaveAs
    • SelectAll
    • Stop
    • Undo
  • In ComponentCommands
    • ExtendSelectionDown
    • ExtendSelectionLeft
    • ExtendSelectionRight
    • ExtendSelectionUp
    • MoveDown
    • MoveFocusBack
    • MoveFocusDown
    • MoveFocusForward
    • MoveFocusPageDown
    • MoveFocusPageUp
    • MoveFocusUp
    • MoveLeft
    • MoveRight
    • MoveToEnd
    • MoveToHome
    • MoveToPageDown
    • MoveToPageUp
    • MoveUp
    • ScrollByLine
    • ScrollPageDown
    • ScrollPageLeft
    • ScrollPageRight
    • ScrollPageUp
    • SelectToEnd
    • SelectToHome
    • SelectToPageDown
    • SelectToPageUp
  • In MediaCommands
    • BoostBass
    • ChannelDown
    • ChannelUp
    • DecreaseBass
    • DecreaseMicrophoneVolume
    • DecreaseTreble
    • DecreaseVolume
    • FastForward
    • IncreaseBass
    • IncreaseMicrophoneVolume
    • IncreaseTreble
    • IncreaseVolume
    • MuteMicrophoneVolume
    • MuteVolume
    • NextTrack
    • Pause
    • Play
    • PreviousTrack
    • Record
    • Rewind
    • Select
    • Stop
    • ToggleMicrophoneOnOff
    • TogglePlayPause

More commands coming next time–in NavigationCommands and EditingCommands.

#347 – How to Set Content Property for Button Based on Command

When you set the Command property of a MenuItem, the menu item automatically picks up a label from the command object, so you don’t need to set the menu item’s Header property.  Unfortunately, this doesn’t work for Button controls.

If you do want to set a Button control’s Content property based on the Text property of the associated command, you can do this in either XAML or code.

To set Content based on command in XAML:

        <Button Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"
                Command="ApplicationCommands.Open"
                VerticalAlignment="Center" Padding="10,5" Margin="5"/>

To set the Content in code:

            btnOpen.Content = ApplicationCommands.Open.Text;

#346 – No Need to Set Header Property for MenuItem When Using Commands

If you use one of the preexisting RoutedUICommand objects for a WPF command, e.g. ApplicationCommands.Open, you’ll notice that the RoutedUICommand instance has a Text property.  This property in the command is used to set the label appearing on any MenuItem instances that have attached to the command by setting their Command property.  You don’t need to set the menu item’s Header property explicitly.

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


Notice that the text for each menu item is automatically filled in, since the text strings are defined in the RoutedUICommand object.  Also notice that some of the commands also define key gestures (e.g. Ctrl+O) for executing the command.

#345 – WPF Command Model is Preferred over Traditional Event Handler Model

In an application, you often need to execute some code in response to a user action.  In WPF, you can use the new command model to respond to user actions or you can use the event handler model that Windows Forms used.

In the event handler model, you wire up event handlers to the code that does the actual work.

With this approach, you still have to add all of the individual event handlers and you need to write code to manage state, i.e. figure out when the user is allowed to click the buttons/menus and enable/disable them.

In the WPF command model, a single command object is bound to the handler code and each control links to that command.  The command object also adds support for state.

So the benefits of the WPF command model are:

  • Less plumbing code to write (no event handlers)
  • Automatically handle control enabled/disabled state

#344 – The CommandBinding CanExecute Event Determines Whether a Button is Enabled

When you associate a button’s Command property with a CommandBinding object,and bind the CommandBinding object to both Executed and CanExecute handlers, the Button control will automatically toggle between enabled/disabled, depending on the code in the CanExecute method.

Suppose we create two buttons, binding them to open/close commands.

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <Button Content="Open" Command="ApplicationCommands.Open"
                VerticalAlignment="Center" Padding="10,5" Margin="5"/>
        <Button Content="Close" Command="ApplicationCommands.Close"
                VerticalAlignment="Center" Padding="10,5" Margin="5"/>
    </StackPanel>

Then we create a CommandBinding and associated handlers.

		public MainWindow()
		{
			this.InitializeComponent();

            CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, Open_Executed, Open_CanExecute));
            CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, Close_Executed, Close_CanExecute));
        }

        private bool isOpen = false;

        public void Open_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("Open");
            isOpen = true;
        }

        public void Open_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = !isOpen;
        }

        public void Close_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("Close");
            isOpen = false;
        }

        public void Close_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = isOpen;
        }

The buttons will now automatically be enabled/disabled, depending on the value of isOpen.

#343 – Associating Multiple Controls with the Same Command

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?
        }

#342 – Binding a Button to a Command

In WPF, the preferred method for executing some code when a button is clicked is to use a commandA command is an object that represents an action to be taken and is bound to a particular method that performs the action.  The button is then associated with the command by setting its Command property.

Here’s an example.

        <Button Content="Open" Command="ApplicationCommands.Open" />

ApplicationCommands.Open is a predefined command that is just a placeholder that you bind to some “open” logic in your application.  You do this by adding a new CommandBinding object to the parent window’s CommandBindings collection.

You specify handlers for the Executed and CanExecute events of the command.

		public MainWindow()
		{
			this.InitializeComponent();

            CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, Open_Executed, Open_CanExecute));
        }

        public void Open_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            // Open file here
        }

        public void Open_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;   // Can we open file?
        }
Follow

Get every new post delivered to your Inbox.

Join 312 other followers