Visão geral de Comando

Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.

This overview defines what commands are in WPF, which classes are part of the commanding model, and how to use and create commands in your applications.

This topic contains the following sections:

  • What Are Commands?

  • Simple Command Example in WPF

  • Four Main Concepts in WPF Commanding

  • Command Library

  • Creating Custom Commands

What Are Commands?

Comandos têm várias finalidades. O primeiro objetivo é separar a semântica e o objeto que chama um comando da lógica que executa o comando. Isso permite que vários e fontes diferentes para invocar a mesma lógica de comando e ele permite que a lógica de comando para ser personalizado para destinos diferentes. Por exemplo, as operações de edição Copy, Recortar, e Colar, que são encontrados em muitos aplicativos, pode ser chamado por meio de ações de usuário diferente se eles são implementados usando comandos. Um aplicativo pode permitir que um usuário recortar o texto ou objetos selecionados clicando um botão, a escolha de um item em um menu ou usando uma combinação de teclas, como, por exemplo, CTRL + X. Usando comandos, você pode vincular cada tipo de ação do usuário para a mesma lógica.

Outro objetivo de comandos é indicar se uma ação está disponível. Para continuar o exemplo de recortar um objeto ou texto, a ação só faz sentido quando algo está selecionado. Se um usuário tentar recortar um objeto ou texto sem ter que nada selecionado, aconteceria nada. Para indicar isso ao usuário, muitos aplicativos desativar botões e itens de menu, para que o usuário sabe se é possível realizar uma ação. Um comando pode indicar se uma ação é possível implementar a CanExecute método. Um botão pode se inscrever a CanExecuteChanged eventos e desativado se CanExecute retorna false ou ser ativadas se CanExecute retorna true.

A semântica de um comando pode ser consistente em aplicativos e classes, mas a lógica da ação é específica para o objeto específico tratado. A combinação de teclas CTRL + X chama o Recortar comando em classes de texto, classes de imagem e navegadores da Web, mas a lógica real para executar o Recortar operação é definida pelo aplicativo que executa o recorte. A RoutedCommand permite que os clientes a implementar a lógica. Um objeto de texto pode recortar o texto selecionado na área de transferência, enquanto um objeto de imagem pode recortar a imagem selecionada. Quando um aplicativo lida com o Executed evento, ele tem acesso ao destino do comando e pode levar a ação apropriada, dependendo de tipo. do destino

Simple Command Example in WPF

The simplest way to use a command in WPF is to use a predefined RoutedCommand from one of the command library classes; use a control that has native support for handling the command; and use a control that has native support for invoking a command. The Paste command is one of the predefined commands in the ApplicationCommands class. O TextBox controle desenvolveu-se na lógica de tratamento de Paste comando. And the MenuItem class has native support for invoking commands.

The following example shows 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.

<StackPanel>
  <Menu>
    <MenuItem Command="ApplicationCommands.Paste" />
  </Menu>
  <TextBox />
</StackPanel>
            ' Creating the UI objects
            Dim mainStackPanel As New StackPanel()
            Dim pasteTextBox As New TextBox()
            Dim stackPanelMenu As New Menu()
            Dim pasteMenuItem As New MenuItem()

            ' Adding objects to the panel and the menu
            stackPanelMenu.Items.Add(pasteMenuItem)
            mainStackPanel.Children.Add(stackPanelMenu)
            mainStackPanel.Children.Add(pasteTextBox)

            ' Setting the command to the Paste command
            pasteMenuItem.Command = ApplicationCommands.Paste
// Creating the UI objects
StackPanel mainStackPanel = new StackPanel();
TextBox pasteTextBox = new TextBox();
Menu stackPanelMenu = new Menu();
MenuItem pasteMenuItem = new MenuItem();

// Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem);
mainStackPanel.Children.Add(stackPanelMenu);
mainStackPanel.Children.Add(pasteTextBox);

// Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste;

// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;

Four Main Concepts in WPF Commanding

O modelo de comando roteado no WPF pode ser dividida em quatro conceitos principais: o comando, a fonte de comando, o destino de comando e a vinculação de comando:

  • The command is the action to be executed.

  • The command source is the object which invokes the command.

  • The command target is the object that the command is being executed on.

  • The command binding is the object which maps the command logic to the command.

In the previous example, the Paste command is the command, the MenuItem is the command source, the TextBox is the command target, and the command binding is supplied by the TextBox control. It is worth noting that it is not always the case that the CommandBinding is supplied by the control that is the command target class. Quite often the CommandBinding must be created by the application developer, or the CommandBinding might be attached to an ancestor of the command target.

Commands

Comandos em WPF são criados por meio da implementação de ICommand interface. ICommandexpõe dois métodos, Execute, e CanExecutee um evento, CanExecuteChanged. Executeexecuta as ações que estão associadas com o comando. CanExecute determina se o comando pode executar o destino de comando atual. CanExecuteChangedé gerado se o Gerenciador de comando que centraliza as operações de comando detecta uma alteração na fonte de comando que pode invalidar um comando que foi gerado, mas ainda não foi executado pela vinculação de comando. The WPF implementation of ICommand is the RoutedCommand class and is the focus of this overview.

The main sources of input in WPF are the mouse, the keyboard, ink, and routed commands. As entradas mais orientadas a dispositivo usam um RoutedEvent para notificar os objetos em uma página de aplicativo que ocorreu um evento de entrada. A RoutedCommand não é diferente. The Execute and CanExecute methods of a RoutedCommand do not contain the application logic for the command, but rather they raise routed events that tunnel and bubble through the element tree until they encounter an object with a CommandBinding. The CommandBinding contains the handlers for these events and it is the handlers that perform the command. Para obter mais informações sobre roteamento de eventos em WPF, consulte Visão geral sobre eventos roteados.

The Execute method on a RoutedCommand raises the PreviewExecuted and the Executed events on the command target. The CanExecute method on a RoutedCommand raises the CanExecute and PreviewCanExecute events on the command target. These events tunnel and bubble through the element tree until they encounter an object which has a CommandBinding for that particular command.

WPFFornece um conjunto de comandos roteados comuns, espalhados por várias classes: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommands, and EditingCommands. 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 Sources

A command source is the object which invokes the command. Examples of command sources are MenuItem, Button, and KeyGesture.

Comando de fontes em WPF geralmente é implementar a ICommandSource interface.

ICommandSourceexpõe três propriedades: Command, CommandTarget, and CommandParameter:

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.

The following example shows how to use a MenuItem in a ContextMenu as a command source for the Properties command.

<StackPanel>
  <StackPanel.ContextMenu>
    <ContextMenu>
      <MenuItem Command="ApplicationCommands.Properties" />
    </ContextMenu>
  </StackPanel.ContextMenu>
</StackPanel>
            Dim cmdSourcePanel As New StackPanel()
            Dim cmdSourceContextMenu As New ContextMenu()
            Dim cmdSourceMenuItem As New MenuItem()

            ' Add ContextMenu to the StackPanel.
            cmdSourcePanel.ContextMenu = cmdSourceContextMenu
            cmdSourcePanel.ContextMenu.Items.Add(cmdSourceMenuItem)

            ' Associate Command with MenuItem.
            cmdSourceMenuItem.Command = ApplicationCommands.Properties
StackPanel cmdSourcePanel = new StackPanel();
ContextMenu cmdSourceContextMenu = new ContextMenu();
MenuItem cmdSourceMenuItem = new MenuItem();

// Add ContextMenu to the StackPanel.
cmdSourcePanel.ContextMenu = cmdSourceContextMenu;
cmdSourcePanel.ContextMenu.Items.Add(cmdSourceMenuItem);

// Associate Command with MenuItem.
cmdSourceMenuItem.Command = ApplicationCommands.Properties;

Typically, a command source will listen to the CanExecuteChanged event. This event informs the command source that the ability of the command to execute on the current command target may have changed. The command source can query the current status of the RoutedCommand by using the CanExecute method. The command source can then disable itself if the command cannot execute. An example of this is a MenuItem graying itself out when a command cannot execute.

An InputGesture can be used as a command source. Two types of input gestures in WPF are the KeyGesture and MouseGesture. Você pode pensar em um KeyGesture como um atalho de teclado, como CTRL + c. A KeyGesture é composto de um Key e um conjunto de ModifierKeys. A MouseGesture is comprised of a MouseAction and an optional set of ModifierKeys.

In order for an InputGesture to act as a command source, it must be associated with a command. There are a few ways to accomplish this. One way is to use an InputBinding.

The following example shows how to create a KeyBinding between a KeyGesture and a RoutedCommand.

<Window.InputBindings>
  <KeyBinding Key="B"
              Modifiers="Control" 
              Command="ApplicationCommands.Open" />
</Window.InputBindings>
            Dim OpenKeyGesture As New KeyGesture(Key.B, ModifierKeys.Control)

            Dim OpenCmdKeybinding As New KeyBinding(ApplicationCommands.Open, OpenKeyGesture)

            Me.InputBindings.Add(OpenCmdKeybinding)
KeyGesture OpenKeyGesture = new KeyGesture(
    Key.B,
    ModifierKeys.Control);

KeyBinding OpenCmdKeybinding = new KeyBinding(
    ApplicationCommands.Open,
    OpenKeyGesture);

this.InputBindings.Add(OpenCmdKeybinding);

Another way to associate an InputGesture to a RoutedCommand is to add the InputGesture to the InputGestureCollection on the RoutedCommand.

The following example shows how to add a KeyGesture to the InputGestureCollection of a RoutedCommand.

            Dim OpenCmdKeyGesture As New KeyGesture(Key.B, ModifierKeys.Control)

            ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture)
KeyGesture OpenCmdKeyGesture = new KeyGesture(
    Key.B,
    ModifierKeys.Control);

ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture);

CommandBinding

A CommandBinding associates a command with the event handlers that implement the command.

The CommandBinding class contains a Command property, and PreviewExecuted, Executed, PreviewCanExecute, and CanExecute events.

Command is the command that the CommandBinding is being associated with. The event handlers which are attached to the PreviewExecuted and Executed events implement the command logic. The event handlers attached to the PreviewCanExecute and CanExecute events determine if the command can execute on the current command target.

The following example shows how to create a CommandBinding on the root Window of an application. The CommandBinding associates the Open command with Executed and CanExecute handlers.

<Window.CommandBindings>
  <CommandBinding Command="ApplicationCommands.Open"
                  Executed="OpenCmdExecuted"
                  CanExecute="OpenCmdCanExecute"/>
</Window.CommandBindings>
            ' Creating CommandBinding and attaching an Executed and CanExecute handler
            Dim OpenCmdBinding As New CommandBinding(ApplicationCommands.Open, AddressOf OpenCmdExecuted, AddressOf OpenCmdCanExecute)

            Me.CommandBindings.Add(OpenCmdBinding)
// Creating CommandBinding and attaching an Executed and CanExecute handler
CommandBinding OpenCmdBinding = new CommandBinding(
    ApplicationCommands.Open,
    OpenCmdExecuted,
    OpenCmdCanExecute);

this.CommandBindings.Add(OpenCmdBinding);

Next, the ExecutedRoutedEventHandler and a CanExecuteRoutedEventHandler are created. The ExecutedRoutedEventHandler opens a MessageBox that displays a string saying the command has been executed. The CanExecuteRoutedEventHandler sets the CanExecute property to true.

Private Sub OpenCmdExecuted(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
    Dim command, targetobj As String
    command = CType(e.Command, RoutedCommand).Name
    targetobj = CType(sender, FrameworkElement).Name
    MessageBox.Show("The " + command + " command has been invoked on target object " + targetobj)
End Sub
void OpenCmdExecuted(object target, ExecutedRoutedEventArgs e)
{
    String command, targetobj;
    command = ((RoutedCommand)e.Command).Name;
    targetobj = ((FrameworkElement)target).Name;
    MessageBox.Show("The " + command +  " command has been invoked on target object " + targetobj);
}
Private Sub OpenCmdCanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
    e.CanExecute = True
End Sub
void OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

A CommandBinding is attached to a specific object, such as the root Window of the application or a control. The object that the CommandBinding is attached to defines the scope of the binding. For example, a CommandBinding attached to an ancestor of the command target can be reached by the Executed event, but a CommandBinding attached to a descendant of the command target cannot be reached. This is a direct consequence of the way a RoutedEvent tunnels and bubbles from the object that raises the event.

In some situations the CommandBinding is attached to the command target itself, such as with the TextBox class and the Cut, Copy, and Paste commands. Quite often though, it is more convenient to attach the CommandBinding to an ancestor of the command target, such as the main Window or the Application object, especially if the same CommandBinding can be used for multiple command targets. Essas são as decisões de design, que você desejará considerar quando você está criando sua infra-estrutura de comando.

Command Target

The command target is the element on which the command is executed. With regards to a RoutedCommand, the command target is the element at which routing of the Executed and CanExecute starts. As noted previously, 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.

The command source can explicitly set the command target. If the command target is not defined, the element with keyboard focus will be used as the command target. One of the benefits of using the element with keyboard focus as the command target is that it allows the application developer to use the same command source to invoke a command on multiple targets without having to keep track of the command target. For example, if a MenuItem invokes the Paste command in an application that has a TextBox control and a PasswordBox control, the target can be either the TextBox or PasswordBox depending on which control has keyboard focus.

The following example shows how to explicitly set the command target in markup and in code behind.

<StackPanel>
  <Menu>
    <MenuItem Command="ApplicationCommands.Paste"
              CommandTarget="{Binding ElementName=mainTextBox}" />
  </Menu>
  <TextBox Name="mainTextBox"/>
</StackPanel>
            ' Creating the UI objects
            Dim mainStackPanel As New StackPanel()
            Dim pasteTextBox As New TextBox()
            Dim stackPanelMenu As New Menu()
            Dim pasteMenuItem As New MenuItem()

            ' Adding objects to the panel and the menu
            stackPanelMenu.Items.Add(pasteMenuItem)
            mainStackPanel.Children.Add(stackPanelMenu)
            mainStackPanel.Children.Add(pasteTextBox)

            ' Setting the command to the Paste command
            pasteMenuItem.Command = ApplicationCommands.Paste
// Creating the UI objects
StackPanel mainStackPanel = new StackPanel();
TextBox pasteTextBox = new TextBox();
Menu stackPanelMenu = new Menu();
MenuItem pasteMenuItem = new MenuItem();

// Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem);
mainStackPanel.Children.Add(stackPanelMenu);
mainStackPanel.Children.Add(pasteTextBox);

// Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste;

// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;

The CommandManager

The CommandManager serves a number of command related functions. It provides a set of static methods for adding and removing PreviewExecuted, Executed, PreviewCanExecute, and CanExecute event handlers to and from a specific element. It provides a means to register CommandBinding and InputBinding objects onto a specific class. The CommandManager also provides a means, through the RequerySuggested event, to notify a command when it should raise the CanExecuteChanged event.

The InvalidateRequerySuggested method forces the CommandManager to raise the RequerySuggested event. This is useful for conditions that should disable/enable a command but are not conditions that the CommandManager is aware of.

Command Library

WPF provides a set of predefined commands. A biblioteca de comando consiste em classes a seguir: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommands, and the ComponentCommands. Essas classes fornecem comandos como Cut, BrowseBack e BrowseForward, Play, Stop, e Pause.

Many of these commands include a set of default input bindings. Por exemplo, se você especificar que o seu aplicativo lida com o comando copy, você obtém automaticamente o teclado na vinculação "ctrl + C" Você também obtém ligações para outros dispositivos de entrada, como Tablet PC os gestos de caneta e informações de fala.

When you reference commands in the various command libraries using XAML, you can usually omit the class name of the library class that exposes the static command property. Generally, the command names are unambiguous as strings, and the owning types exist to provide a logical grouping of commands but are not necessary for disambiguation. For instance, you can specify Command="Cut" rather than the more verbose Command="ApplicationCommands.Cut". This is a convenience mechanism that is built in to the WPF XAML processor for commands (more precisely, it is a type converter behavior of ICommand, which the WPF XAML processor references at load time).

Creating Custom Commands

If the commands in the command library classes do not meet your needs, then you can create your own commands. There are two ways to create a custom command. The first is to start from the ground up and implement the ICommand interface. The other way, and the more common approach, is to create a RoutedCommand or a RoutedUICommand.

Para obter um exemplo de criação de um personalizado RoutedCommand, consulte criar uma amostra de RoutedCommand personalizado.

Consulte também

Tarefas

Como: Implement ICommandSource

Como: Add a Command to a MenuItem

Referência

RoutedCommand

CommandBinding

InputBinding

CommandManager

Conceitos

Input Overview

Visão geral sobre eventos roteados

Outros recursos

Criar uma amostra de RoutedCommand personalizado