Compartilhar via


Visão geral de Comando

Comando é um mecanismo de entrada no Windows Presentation Foundation (WPF) que fornece manipulação de entrada em um nível mais semântico do que a entrada do dispositivo. São exemplos de comandos operações Copiar,Recortar, e Colar encontrado no muitos aplicativos.

Esta visão geral define os comandos que estão em WPF, quais classes fazem parte do modelo de comando e como usar e criar comandos em seus aplicativos.

Este tópico contém as seguintes seções.

  • O que são comandos?
  • Exemplo de comando simples no WPF
  • Quatro principais conceitos em Comandos de WPF
  • Biblioteca de comando
  • Criar comandos personalizados
  • Tópicos relacionados

O que são comandos?

O sistema de comando no WPF baseia-se no RoutedCommand e no RoutedEvent. Um comando não precisa ser um RoutedCommand e pode simplesmente implementar o ICommand, que será abordado, mas o grosso desta Visão geral irá focalizar o modelo RoutedCommand.

O que torna os comandos diferente de um simples manipulador de eventos anexado a um botão ou um timer é que os comandos separam a semântica e a origem de uma ação de sua lógica. Isso permite várias e origens diferentes para invocar a mesma lógica de comando e permite que a lógica de comando para ser personalizado para destinos diferentes.

Exemplos de comandos são as operações de edição de Copiar ,Recortar e Colar , que são encontrados em muitos aplicativos. A semântica dos comandos são consistente entre aplicativos e classes, mas a lógica da ação é específico para o objeto tratado. A combinação de teclas CTRL+X invoca o Recortar comando no texto classes, classes de imagem e navegadores da Web, mas a lógica real para executar o Recortar operação é definida pelo objeto ou o aplicativo no qual o corte ocorre e não na fonte que o comando invocado. Um objeto de texto pode recortar o texto selecionado para a Área de transferência, enquanto um objeto de imagem pode recortar a imagem selecionada, mas a mesma fonte de comando, um KeyGesture ou um botão ToolBar, pode ser usado para chamar o comando em ambas as classes.

Exemplo de comando simples no WPF

A maneira mais simples para usar um comando WPF é usar uma das classes predefinidas RoutedCommand da biblioteca de classes de comando; usar um controle que tenha suporte nativo para manipular o comando; e usar um controle que tenha suporte nativo para invocar um comando. O comando Paste é um dos comandos predefinidos na classe ApplicationCommands. O controle TextBox foi construído na lógica para manipular o comando Paste. E a classe MenuItem possui suporte nativo para chamar comandos.

O exemplo a seguir mostra como configurar um MenuItem de modo que quando ele for clicado ele chamará o comando Paste em um TextBox, supondo que o TextBox tenha o foco de teclado.

<StackPanel>
  <Menu>
    <MenuItem Command="ApplicationCommands.Paste" />
  </Menu>
  <TextBox />
</StackPanel>
// 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;

Quatro principais conceitos em Comandos de WPF

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

  • O comando é a ação a ser executada.

  • A fonte de comando é o objeto que chama o comando.

  • O destino de comando é o objeto em que o comando está sendo executado.

  • A vinculação de comando é o objeto que mapeia a lógica de linha de comando para o comando.

No exemplo anterior, o comando Paste é o comando, MenuItem é a fonte de comando, TextBox é o destino de comando, e a vinculação de comando é fornecida pelo controle TextBox. É importante observar que não é sempre o caso que a CommandBinding é fornecido pelo controle que é a classe de destino de comando. Bastante comumente o CommandBinding deve ser criado pelo desenvolvedor de aplicativos, ou o CommandBinding pode ser anexado a um predecessor do destino de comando.

Comandos

Comandos em WPF são criados por implementar o ICommand interface. ICommand apresenta dois métodos Execute, e CanExecutee um evento CanExecuteChanged. Execute executa as ações que estão associadas com o comando. CanExecute Determina se o comando pode ser executado no seu corrente destino. CanExecuteChanged é gerado se o Gerenciador de comando que centraliza as operações de comando detectar uma alterar na fonte de comando que pode invalidar um comando que foi gerado, mas ainda não foram executado por vinculação de comando. A implementação WPF de ICommand é a classe RoutedCommand e é foco desta visão geral.

As principais fontes da entrada no WPF são o mouse, o teclado, tinta e comandos roteados. As entradas mais orientadas a dispositivos usam um RoutedEvent para notificar objetos em uma página que ocorreu um evento de entrada do aplicativo. Um RoutedCommand não é diferente. Os métodos Execute e CanExecute de um RoutedCommand não contém a lógica do aplicativo para o comando, mas em vez disso, eles geram eventos roteados que são tunelados e borbulhados através da árvore de elemento até que eles encontrem um objeto com um CommandBinding. O CommandBinding contém os manipuladores para esses eventos e são os manipuladores que executam o comando. Para obter mais informações sobre roteamento de eventos em WPF, consulte Visão geral sobre eventos roteados.

O método Execute em um RoutedCommand gera os eventos PreviewExecuted e os Executed no destino de comando. O método CanExecute em um RoutedCommand gera os eventos CanExecute e os PreviewCanExecute no destino de comando. Esses eventos são tunelados e de borbulhados através da árvore de elemento até que eles encontrar um objeto que tem um CommandBinding para esse comando em particular.

WPF Fornece um conjunto de comandos roteados comuns espalhados entre várias classes: MediaCommands, ApplicationCommands, , NavigationCommands, ComponentCommands, e EditingCommands. Essas classes consistem somente de objetos RoutedCommand e não a lógica de implementação do comando. A lógica de implementação é de responsabilidade do objeto no qual o comando está sendo executado.

Fontes de comando

Uma fonte de comando é o objeto que chama o comando. Exemplos de fontes de comando são MenuItem, Button e KeyGesture.

Fontes de comando no WPF geralmente implementam a interface ICommandSource.

ICommandSource expõe três propriedades: Command, CommandTarget, e CommandParameter:

As classes WPF que implementam ICommandSource são ButtonBase, MenuItem, Hyperlink e InputBinding. ButtonBase, MenuItem e Hyperlink invocam um comando quando eles são clicados, e um InputBinding invoca um comando quando o InputGesture associado é realizado.

O seguinte exemplo mostra como usar um MenuItem em um ContextMenu como a fonte de comando para o comando Properties.

<StackPanel>
  <StackPanel.ContextMenu>
    <ContextMenu>
      <MenuItem Command="ApplicationCommands.Properties" />
    </ContextMenu>
  </StackPanel.ContextMenu>
</StackPanel>
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;

Normalmente, uma fonte de comando escutará o evento CanExecuteChanged. Esse evento informa a fonte de comando que pode ter alterado a capacidade do comando de ser executado no destino de comando atual. A fonte de comando pode consultar o status atual do RoutedCommand usando o método CanExecute. A fonte de comando pode então se desativar se o comando não pode ser executado. Um exemplo disso é um MenuItem se retirando quando não é possível executar um comando.

Um InputGesture pode ser usado como uma fonte de comando. Dois tipos de gestos de entrada no WPF são KeyGesture e MouseGesture. Você pode considerar um KeyGesture sistema autônomo um atalho de teclado, sistema autônomo CTRL+C. A KeyGesture é composto de um Key e um conjunto de ModifierKeys. Um MouseGesture é composto de um MouseAction e um conjunto opcional de ModifierKeys.

Para um InputGesture agir como uma fonte de comando, ele deve ser associado a um comando. Há algumas maneiras para fazer isso. Uma maneira é usar um InputBinding.

O exemplo a seguir mostra como criar um KeyBinding entre um KeyGesture e um RoutedCommand.

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

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

this.InputBindings.Add(OpenCmdKeybinding);

Outra maneira para associar um InputGesture para um RoutedCommand é adicionar a InputGesture ao InputGestureCollection na RoutedCommand.

O exemplo a seguir mostra como adicionar um KeyGesture a InputGestureCollection de um RoutedCommand.

KeyGesture OpenCmdKeyGesture = new KeyGesture(
    Key.B,
    ModifierKeys.Control);

ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture);

CommandBinding

Um CommandBinding associa um comando com os manipuladores de eventos que implementam o comando.

A classe CommandBinding contém uma propriedade Command e PreviewExecuted, Executed, PreviewCanExecute e eventos CanExecute.

Command é o comando que o CommandBinding está sendo associado. Os manipuladores de eventos que estão conectados aos eventos PreviewExecuted e Executed implementam a lógica de comando. Os manipuladores de evento anexado aos eventos PreviewCanExecute e CanExecute determinam se o comando pode executar de destino de comando atual.

O exemplo a seguir mostra como criar um CommandBinding na Window raiz de um aplicativo. O CommandBinding associa o comando Open com Executed e manipuladores CanExecute.

<Window.CommandBindings>
  <CommandBinding Command="ApplicationCommands.Open"
                  Executed="OpenCmdExecuted"
                  CanExecute="OpenCmdCanExecute"/>
</Window.CommandBindings>
// Creating CommandBinding and attaching an Executed and CanExecute handler
CommandBinding OpenCmdBinding = new CommandBinding(
    ApplicationCommands.Open,
    OpenCmdExecuted,
    OpenCmdCanExecute);

this.CommandBindings.Add(OpenCmdBinding);

Depois, o ExecutedRoutedEventHandler e o CanExecuteRoutedEventHandler são criados. O ExecutedRoutedEventHandler abre um MessageBox que exibe uma sequência de caracteres informando que o comando foi executado. O CanExecuteRoutedEventHandler define a propriedade CanExecute para 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;
}

Um CommandBinding está conectado a um objeto específico, como a raiz do aplicativo ou um controle Window. O objeto CommandBinding anexado define o escopo da ligação. Por exemplo, um CommandBinding anexado a um predecessor do comando destino pode ser alcançado pelo evento Executed, mas uma CommandBinding anexado a um descendente do comando de destino não pode ser alcançado. Esta é uma consequência direta da maneira como um RoutedEvent é tunelado e borbulhado a partir do objeto que gera o evento.

Em algumas situações o CommandBinding está conectada ao destino de comando em si, como na classe TextBox e os comandos Cut, Copy e Paste. Bem frequentemente, no entanto, é mais conveniente anexar o CommandBinding a um predecessor do destino de comando, como o principal Window ou o objeto de aplicativo, especialmente se o mesmo CommandBinding pode ser usado para vários destinos de comando. Essas são decisão de design que você precisará considerar quando você cria a infraestrutura de comandos.

Destino de Comando

O destino de comando é o elemento no qual o comando é executado. Com relação aos RoutedCommand, o destino de comando é o elemento no qual o roteamento de Executed e CanExecute inicia. Conforme observado anteriormente, em WPF a propriedade CommandTarget no ICommandSource só é aplicável quando o ICommand é um RoutedCommand. Se o CommandTarget é definida em um ICommandSource e o comando correspondente não é um RoutedCommand, o destino de comando é ignorado.

A fonte de comando pode explicitamente definir o destino de comando. Se o destino de comando não estiver definido, o elemento com o foco do teclado será o destino de comando. Uma das vantagens de usar o elemento com o foco do teclado como o destino de comando é que ele permite desenvolvedor do aplicativo usar a mesma fonte de comando para invocar um comando em vários destinos sem ter que manter o controle de destino de comando. Por exemplo, se um MenuItem chama o comando Colar em um aplicativo que tenha um controle TextBox e um controle PasswordBox, o destino pode ser o TextBox ou PasswordBox dependendo qual controle tem o foco do teclado.

O exemplo a seguir mostra como definir explicitamente o destino de comando na marcação e no código.

<StackPanel>
  <Menu>
    <MenuItem Command="ApplicationCommands.Paste"
              CommandTarget="{Binding ElementName=mainTextBox}" />
  </Menu>
  <TextBox Name="mainTextBox"/>
</StackPanel>
// 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;

O CommandManager

O CommandManager serve um número de funções relacionadas a comando. Ele fornece um conjunto de métodos estáticos para adicionar e remover manipuladores de eventos PreviewExecuted, Executed, PreviewCanExecute e CanExecute para e de um elemento específico. Ele fornece um meio para registrar objetos CommandBinding e InputBinding em uma classe específica. O CommandManager também fornece um meio, por meio do evento RequerySuggested, para notificar um comando quando ele deve gerar o evento CanExecuteChanged.

O método InvalidateRequerySuggested força o CommandManager a gerar o evento RequerySuggested. Isso é útil em condições que devem desativar/ativar um comando mas não o é condições que o CommandManager está ciente disto. Para obter um exemplo de chamada InvalidateRequerySuggested para forçar o CommandManager para elevar o RequerySuggested evento, consulte Desativar o comando Origem por meio do exemplo de timer do dispatcher exemplo.

Biblioteca de comando

WPF fornece um conjunto de comandos predefinidos. A biblioteca de comando consiste em classes a seguir: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommandse o ComponentCommands. Essas classes fornecem comandos como Cut, BrowseBack e BrowseForward, Play, Stop e Pause.

Muitos desses comandos incluem um conjunto de ligações de entrada padrão. Por exemplo, se você especificar que seu aplicativo lida com o comando copy, você obtém automaticamente o teclado vinculação "CTRL+C" Você também obterá ligações para outros dispositivos de entrada, sistema autônomoTablet PC gestos da caneta e informações de fala.

Quando você faz referência a comandos nas várias bibliotecas de comando usando XAML, geralmente você pode omitir a nome da classe da classe da biblioteca que expõe a propriedade estático de linha de comando. Geralmente, os nomes de comando são não ambíguos como sequências de caracteres, e os tipos de propriedade existirem para fornecer um agrupamento lógico de comandos mas não são necessárias para eliminar ambiguidades. Por exemplo, você pode especificar Command="Cut" em vez de Command="ApplicationCommands.Cut" mais detalhado. Este é um mecanismo de conveniência interna para o processador WPF XAML de comandos (mais precisamente, ele é um comportamento de conversão de tipos de ICommand, que o WPF XAML processador faz referência em tempo de carregamento).

Criar comandos personalizados

Se os comandos de classes da biblioteca de comando não atenderem às suas necessidades, então você pode criar seus próprios comandos. Há duas maneiras para criar um comando personalizado. A primeira é para iniciar desde o início até e implementar a interface ICommand. A outra maneira e a abordagem mais comum, é criar um RoutedCommand ou um RoutedUICommand.

Para obter um exemplo de como criar um personalizada RoutedCommand, consulte Criar um exemplo de RoutedCommand Personalizar.

Consulte também

Tarefas

Criar um exemplo de RoutedCommand Personalizar

Como: Implement ICommandSource

Como: Add a Command to a MenuItem

Desativar o comando Origem por meio do exemplo de timer do dispatcher

Conceitos

Input Overview

Visão geral sobre eventos roteados

Referência

RoutedCommand

CommandBinding

InputBinding

CommandManager