Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Comando é um mecanismo de entrada no WPF (Windows Presentation Foundation) que fornece tratamento de entrada em um nível mais semântico do que a entrada do dispositivo. Exemplos de comandos são as operações Copiar, Recortar e Colar encontradas em muitos aplicativos.
Essa visão geral define quais comandos estão no 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
Os comandos têm várias finalidades. A primeira finalidade é separar a semântica e o objeto que invoca um comando da lógica que executa o comando. Isso permite que várias fontes diferentes invoquem a mesma lógica de comando e permite que a lógica de comando seja personalizada para destinos diferentes. Por exemplo, as operações de edição Copiar, Recortar e Colar, que são encontradas em muitos aplicativos, podem ser invocadas usando ações de usuário diferentes se forem implementadas usando comandos. Um aplicativo pode permitir que um usuário corte objetos ou texto selecionados clicando em um botão, escolhendo um item em um menu ou usando uma combinação de chaves, como CTRL+X. Usando comandos, você pode associar cada tipo de ação do usuário à mesma lógica.
Outra finalidade dos comandos é indicar se uma ação está disponível. Para continuar o exemplo de corte de um objeto ou texto, a ação só faz sentido quando algo é selecionado. Se um usuário tentar cortar um objeto ou texto sem ter nada selecionado, nada acontecerá. Para indicar isso ao usuário, muitos aplicativos desabilitam botões e itens de menu para que o usuário saiba se é possível executar uma ação. Um comando pode indicar se uma ação é possível implementando o CanExecute método. Um botão pode assinar o evento CanExecuteChanged e ser desabilitado se CanExecute retornar false
ou ser habilitado se CanExecute retornar true
.
A semântica de um comando pode ser consistente entre aplicativos e classes, mas a lógica da ação é específica para o objeto específico que foi agido. A combinação de teclas CTRL+X invoca o comando Cut em classes de texto, classes de imagem e navegadores da Web, mas a lógica real para realizar a operação Cortar é definida pelo aplicativo que realiza o corte. Um RoutedCommand permite que os clientes implementem a lógica. 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. Quando um aplicativo manipula o Executed evento, ele tem acesso ao destino do comando e pode tomar as medidas apropriadas dependendo do tipo do destino.
Exemplo de comando simples no WPF
A maneira mais simples de usar um comando no WPF é usar um predefinido RoutedCommand de uma das classes de biblioteca de comandos; usar um controle que tenha suporte nativo para lidar com o comando e usar um controle que tenha suporte nativo para invocar um comando. O Paste comando é um dos comandos predefinidos na ApplicationCommands classe. O TextBox controle tem lógica interna para lidar com o Paste comando. E a MenuItem classe tem suporte nativo para invocar comandos.
O exemplo a seguir mostra como configurar um MenuItem para que, quando ele for clicado, o comando Paste seja invocado em um TextBox, assumindo que o TextBox tem o foco do 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;
// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;
' 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
Quatro conceitos principais no comando do WPF
O modelo de comando roteado no WPF pode ser dividido em quatro conceitos principais: o comando, a origem do comando, o destino do comando e a associação de comando:
O comando é a ação a ser executada.
A origem do comando é o objeto que invoca o comando.
O destino de comando é o objeto no qual o comando está sendo executado.
A associação de comando é o objeto que mapeia a lógica de comando para o comando.
No exemplo anterior, o Paste comando é o comando, a MenuItem origem do comando, o TextBox destino do comando e a associação de comandos é fornecida pelo TextBox controle. É importante observar que nem sempre o `CommandBinding` é fornecido pela classe que é o alvo do comando. Frequentemente, o CommandBinding deve ser criado pelo desenvolvedor de aplicativos, ou o CommandBinding pode ser anexado a um ancestral do destino de comando.
Comandos
Os comandos no WPF são criados implementando a ICommand interface. ICommand expõe dois métodos, Executee CanExecute, e um evento, CanExecuteChanged. Execute executa as ações associadas ao comando. CanExecute determina se o comando pode ser executado no destino de comando atual. CanExecuteChanged será gerado se o gerenciador de comandos que centraliza as operações de comando detectar uma alteração na origem do comando que pode invalidar um comando que foi gerado, mas ainda não executado pela associação de comando. A implementação WPF de ICommand é a classe RoutedCommand e é o objeto principal desta visão geral.
As principais fontes de entrada no WPF são o mouse, o teclado, a tinta digital e os comandos roteados. As entradas mais orientadas ao dispositivo usam um RoutedEvent para notificar objetos em uma página de aplicativo de que ocorreu um evento de entrada. A 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 sim geram eventos roteados que tunelam e borbulham através da árvore de elementos até encontrarem um objeto com um CommandBinding. Os manipuladores desses eventos estão contidos em CommandBinding e são eles que executam o comando. Para obter mais informações sobre o roteamento de eventos no WPF, consulte Visão geral de eventos roteados.
O método Execute em um RoutedCommand gera os eventos PreviewExecuted e Executed no alvo do comando. O método CanExecute em um RoutedCommand gera os eventos CanExecute e PreviewCanExecute no destino de comando. Esses eventos percorrem em túnel e em bolha através da árvore de elementos até encontrar um objeto que tenha um CommandBinding para esse comando específico.
O WPF fornece um conjunto de comandos roteados comuns espalhados por várias classes: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommands e EditingCommands. Essas classes consistem apenas nos RoutedCommand objetos e não na lógica de implementação do comando. A lógica de implementação é responsabilidade do objeto no qual o comando está sendo executado.
Fontes de comando
Uma fonte de comando é o objeto que invoca o comando. Exemplos de fontes de comando são MenuItem, Buttone KeyGesture.
As fontes de comando no WPF geralmente implementam a ICommandSource interface.
ICommandSource expõe três propriedades: Command, CommandTargete CommandParameter:
Command é o comando a ser executado quando a origem do comando é invocada.
CommandTarget é o objeto no qual executar o comando. Vale a pena observar que, no WPF, a propriedade CommandTarget em ICommandSource é aplicável apenas quando ICommand é um RoutedCommand. Se o CommandTarget estiver configurado em ICommandSource e o comando correspondente não for RoutedCommand, o alvo do comando será ignorado. Se a CommandTarget não estiver definida, o elemento com foco no teclado será o alvo do comando.
CommandParameter é um tipo de dados definido pelo usuário usado para passar informações para os manipuladores que implementam o comando.
As classes do WPF que implementam ICommandSource são ButtonBase, MenuIteme HyperlinkInputBinding. ButtonBase, MenuIteme Hyperlink invoca um comando quando eles são clicados e um InputBinding invoca um comando quando o InputGesture associado a ele é executado.
O exemplo a seguir mostra como usar um MenuItem em uma ContextMenu como 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;
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
Normalmente, uma fonte de comando ouvirá o evento CanExecuteChanged. Esse evento informa à origem do comando que a capacidade do comando de executar no destino de comando atual pode ter sido alterada. A origem do comando pode consultar o status atual de RoutedCommand usando o método CanExecute. A origem do comando poderá autodesabilitar-se se o comando não puder ser executado. Um exemplo disso é um MenuItem esmaecer quando um comando não pode ser executado.
Um InputGesture pode ser usado como uma fonte de comando. Dois tipos de gestos de entrada no WPF são o KeyGesture e MouseGesture. Você pode pensar em um KeyGesture atalho de teclado, como CTRL+C. Um KeyGesture é composto por um Key e um conjunto de ModifierKeys. Um MouseGesture é composto por um MouseAction e um conjunto opcional de ModifierKeys.
Para que um InputGesture atue como uma fonte de comando, ele deve ser associado a um comando. Há algumas maneiras de 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);
Dim OpenKeyGesture As New KeyGesture(Key.B, ModifierKeys.Control)
Dim OpenCmdKeybinding As New KeyBinding(ApplicationCommands.Open, OpenKeyGesture)
Me.InputBindings.Add(OpenCmdKeybinding)
Outra maneira de associar um InputGesture a um RoutedCommand é adicionar o InputGesture ao InputGestureCollection no RoutedCommand.
O exemplo a seguir mostra como adicionar um KeyGesture ao InputGestureCollection de um RoutedCommand.
KeyGesture OpenCmdKeyGesture = new KeyGesture(
Key.B,
ModifierKeys.Control);
ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture);
Dim OpenCmdKeyGesture As New KeyGesture(Key.B, ModifierKeys.Control)
ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture)
CommandBinding
Um CommandBinding associa um comando aos manipuladores de eventos que implementam o comando.
A CommandBinding classe contém uma Command propriedade, e PreviewExecuted, Executed, PreviewCanExecutee CanExecute eventos.
Command é o comando ao qual o CommandBinding está sendo associado. Os manipuladores de eventos que estão anexados aos eventos PreviewExecuted e Executed implementam a lógica de comando. Os manipuladores de eventos anexados aos eventos PreviewCanExecute e CanExecute determinam se o comando pode ser executado no destino de comando atual.
O exemplo a seguir mostra como criar um CommandBinding na raiz Window de um aplicativo. Associar o comando CommandBinding com os manipuladores Open e Executed.
<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);
' Creating CommandBinding and attaching an Executed and CanExecute handler
Dim OpenCmdBinding As New CommandBinding(ApplicationCommands.Open, AddressOf OpenCmdExecuted, AddressOf OpenCmdCanExecute)
Me.CommandBindings.Add(OpenCmdBinding)
Em seguida, o ExecutedRoutedEventHandler e um CanExecuteRoutedEventHandler são criados. O ExecutedRoutedEventHandler abre um MessageBox que exibe uma cadeia de caracteres dizendo que o comando foi executado. Define CanExecuteRoutedEventHandler a CanExecute propriedade como true
.
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 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 OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
Private Sub OpenCmdCanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
e.CanExecute = True
End Sub
Um CommandBinding é anexado a um objeto específico, como a raiz Window do aplicativo ou um controle. O objeto ao qual o CommandBinding objeto está anexado define o escopo da associação. Por exemplo, um CommandBinding anexado a um ancestral do destino de comando pode ser alcançado pelo Executed evento, mas um CommandBinding anexado a um descendente do destino de comando não pode ser atingido. Isso é uma consequência direta da maneira como o RoutedEvent encaminhamento e propagação de eventos ocorrem a partir do objeto que gera o evento.
Em algumas situações, o CommandBinding é anexado ao próprio destino de comando, como com a classe TextBox e os comandos Cut, Copy e Paste. Geralmente, porém, é mais conveniente anexar a CommandBinding a um ancestral do destino de comando, como o Window principal ou o objeto Application, especialmente se o mesmo CommandBinding puder ser usado para vários destinos de comando. Essas são decisões de design que você desejará considerar ao criar sua infraestrutura de comando.
Alvo de Comando
O destino de comando é o elemento no qual o comando é executado. Em relação a um RoutedCommand, o destino do comando é o elemento no qual o roteamento de Executed e CanExecute inicia. Conforme observado anteriormente, no WPF, a propriedade CommandTarget em ICommandSource só é aplicável quando ICommand for um RoutedCommand. Se o CommandTarget estiver configurado em ICommandSource e o comando correspondente não for RoutedCommand, o alvo do comando será ignorado.
A origem do comando pode definir explicitamente o destino do comando. Se o destino de comando não estiver definido, o elemento com foco no teclado será usado como o destino do comando. Um dos benefícios de usar o elemento com foco no teclado como destino de comando é que ele permite que o desenvolvedor de aplicativos use a mesma origem de comando para invocar um comando em vários destinos sem precisar controlar o destino do comando. Por exemplo, se um comando MenuItem for invocado em um aplicativo que tenha um controle e um controle TextBox, o destino poderá ser ou PasswordBox ou TextBox dependendo de qual controle esteja com o foco do teclado.
O exemplo a seguir mostra como definir explicitamente o destino de comando na marcação e no código subjacente.
<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;
// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;
' 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
O CommandManager
O CommandManager serve uma série de funções relacionadas ao comando. Ele fornece um conjunto de métodos estáticos para adicionar e remover PreviewExecuted, Executed, PreviewCanExecute e CanExecute manipuladores de eventos em um elemento específico. Ele fornece um meio de registrar CommandBinding e InputBinding objetos em uma classe específica. O CommandManager também fornece um meio, por meio do RequerySuggested evento, de notificar um comando quando ele deve gerar o CanExecuteChanged evento.
O InvalidateRequerySuggested método força a CommandManager acionar o RequerySuggested evento. Isso é útil para condições que devem desabilitar/habilitar um comando, mas não são condições das quais o CommandManager esteja ciente.
Biblioteca de comandos
O WPF fornece um conjunto de comandos predefinidos. A biblioteca de comandos consiste nas seguintes classes: ApplicationCommands, , NavigationCommands, MediaCommandse EditingCommands.ComponentCommands Essas classes fornecem comandos como Cut, BrowseBack e BrowseForward, Play, Stop e Pause.
Muitos desses comandos incluem um conjunto de associações de entrada padrão. Por exemplo, se você especificar que seu aplicativo manipula o comando de cópia, você obtém automaticamente a associação de teclado "CTRL+C" Você também obtém associações para outros dispositivos de entrada, como gestos de caneta tablet PC e informações de fala.
Quando você faz referência a comandos nas várias bibliotecas de comandos usando XAML, geralmente pode omitir o nome da classe de biblioteca que expõe a propriedade de comando estático. Geralmente, os nomes de comando são inequívocas como cadeias de caracteres e os tipos proprietários existem para fornecer um agrupamento lógico de comandos, mas não são necessários para a desambiguação. Por exemplo, você pode especificar Command="Cut"
em vez do mais detalhado Command="ApplicationCommands.Cut"
. Esse é um mecanismo de conveniência que é integrado ao processador XAML do WPF para comandos (mais precisamente, é um comportamento de conversor de tipo do qual o processador XAML do WPF faz referência no momento de carga).
Criando comandos personalizados
Se os comandos nas classes de biblioteca de comandos não atenderem às suas necessidades, você poderá criar seus próprios comandos. Há duas maneiras de criar um comando personalizado. A primeira é começar do zero e implementar a ICommand interface. A outra maneira, e a abordagem mais comum, é criar um RoutedCommand ou um RoutedUICommand.
Para obter um exemplo de criação de um personalizado RoutedCommand, consulte Criar um exemplo de RoutedCommand personalizado.
Consulte também
.NET Desktop feedback