Wpf – Menús – ApplicationCommands - Gesture

Descripción general

En este documento voy a hablar de los menús en Wpf y de los commandos definidos en la clase ApplicationCommands

[TOC] Tabla de Contenidos


↑↑↑

Introducción

Existe lo que podemos llamar la forma tradicional de declarar el menú es decir usando el evento Clic para declarar un escuchador que ejecute el código al pulsar la opción del menú, y usar una imagen, normalmente Png, o Jpg. Algo parecido a esto:


↑↑↑

En el diseñador (Codigo xaml)

<DockPanel Grid.Row="0"  x:Name="dockPanelMenu"
            Height="31" Width="Auto"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Top"
            DockPanel.Dock="Top"
            LastChildFill="False">
 
       <Menu x:Name="MenuGeneral" Height="23" Width="Auto" DockPanel.Dock="Top">
             <Separator />
             <MenuItem Header="Guardar" x:Name="MenuArchivoSave"
                       InputGestureText="Ctrl + G" 
                       ToolTip="Guardar un documento del disco" 
                       Click="MenuArchivoSave_Click">
                  <MenuItem.Icon>
                      <Image Width="16" Height="16"  Stretch="UniformToFill"
                             Source="pack://application:,,,/03Vistas_Layer/0302_ImagenesComunes/MenuFile/Save_6530.png" />
                  </MenuItem.Icon>
             </MenuItem>
        </Menu>
</DockPanel>

En la ventana de código

    
Private Sub MenuArchivoSave_Click(sender As Object, e As RoutedEventArgs)
     Throw New NotImplementedException("MenuArchivoSave_Click")
End Sub

Observaciones a este código

Emplea el evento Clic

Para las direcciones de las imágenes utiliza el formato de direcciones pack (más información aquí)

InputGestureText

Esta etiqueta únicamente sirve para que se muestre en la opción correspondiente del menú las teclas que activan la opción de menú. Solo hace eso y nada más.

Es decir, el hecho de que salgan en la opción de menú no quiere decir que funcionen, hay que programarlas específicamente


↑↑↑

Clase ApplicationCommands

La Clase ApplicationCommands, proporciona un conjunto estándar de comandos relacionados con la aplicación, como puedan ser Copy, Paste, Save, New, Etc. El problema es que la implementación específica hay que escribirla, y para ello hay que dar varios pasos.

Paso Uno

En el diseñador (Codigo xaml), Definir CommandBindings

<Window.CommandBindings>
   <!-- Menú archivo -->
   <CommandBinding Command="ApplicationCommands.New"   Executed="NewCommandBinding_Executed" />
   <CommandBinding Command="ApplicationCommands.Open"  Executed="OpenCommandBinding_Executed" />
   <CommandBinding Command="ApplicationCommands.Save"  Executed="SaveCommandBinding_Executed" />
</Window.CommandBindings>

Observa que:

Paso dos

Escribir el código del escuchador en la ventana e código

 Private Sub NewCommandBinding_Executed(sender As Object, e As ExecutedRoutedEventArgs)
    'Este ejemplo toca un sonido (por hacer alguna cosa)
     Dim objBeep As New Microsoft.VisualBasic.Devices.Audio
     objBeep.PlaySystemSound(System.Media.SystemSounds.Beep)
 End Sub

¡¡ Nota!! El IDE lo escribe automáticamente si pulsas el botón derecho del ratón y en el menú emergente escoges la opción [ir a la definición]

Paso Tres

Decirle al menú, que cuando se le pulse, llame a este comando para que se ejecute, y eso se hace con el atributo Command

Ejemplo en la ventana del diseñador Xaml

(Solo escribo una de las opciones del menú)

<MenuItem Header="_Guardar"  
           x:Name="MenuArchivoSave" 
           InputGestureText="Ctrl + G"
           ToolTip="Guardar un documento del disco"
           Command="ApplicationCommands.New" 
           Visibility="Visible">
     <MenuItem.Icon>
         <Image Width="16" Height="16"  Stretch="UniformToFill"  
  Source="pack://application:,,,/03Vistas_Layer/0302_ImagenesComunes/MenuFile/Save_6530.png" />
      </MenuItem.Icon>
 </MenuItem>

Observa que hemos sustituido el atributo [Click] por el atributo [Command]

Paso Cuatro

Definir el InputGestureText para que se ejecute el [Command] usando el teclado

<Window.InputBindings>
<KeyBinding Key="N"  Modifiers="Control"  Command="ApplicationCommands.New" />
<KeyBinding Key="O"  Modifiers="Control"  Command="ApplicationCommands.Open"/>
<KeyBinding Key="F2" Modifiers="Alt"      Command="ApplicationCommands.Print"/>
</Window.InputBindings>

O bien

<Window.InputBindings>
   <KeyBinding Command="ApplicationCommands.New"     Gesture="CTRL+N" />
   <KeyBinding Command="ApplicationCommands.Open"    Gesture="CTRL+O" />
   <KeyBinding Command="ApplicationCommands.Print"   Gesture="Alt+F2" />
</Window.InputBindings>

Es decir o usas los atributos [Key] y [Modifiers] juntos, o usas únicamente el atributo [Gesture]. Microsoft en su documentación indica que no deben usarse a la vez.

Una Observación, las teclas que definas aquí son las que funcionan con el teclado, insisto en que el atributo [InputGestureText] solo muestra la cadena en la opción del menú

Y eso es todo, la opción de menú ya está funcionando sin problemas


↑↑↑

Una opción de menú que no tiene su Command definido

Problema ¿ que ocurre si necesito una opción de menú ( por ejemplo Save All Guardar Todo)

Pues, antes de nada, tendré que definir un Command, luego los pasos a dar son iguales, con la diferencia de que se llama al Command que acabamos de definir.

Paso Cero

En la ventana del diseñador definir el Comando para hacer el trabajo [ Save All], que será algo asi:

 <Window.Resources>
<RoutedUICommand x:Key="SaveAllCmd" 
                      Text="Describe lo que hace este Command, 
                            Por ejemplo, Guardar todos los ficheros abiertos">
<RoutedUICommand.InputGestures>
<KeyGesture>Ctrl+Shift+</KeyGesture>
<!--
    ATENCION.
    InputGestures muestra y ejecuta el comando al pulsar la tecla
    El modificador Ctrl, debe ir el primero
-->
</RoutedUICommand.InputGestures>
</RoutedUICommand>
</Window.Resources>

Paso Uno

En el diseñador (Codigo xaml), Definir CommandBindings

<Window.CommandBindings>
   <!-- Menú archivo -->
   <CommandBinding Command="{StaticResource SaveAllCmd}"
                                                                                               Executed="SaveAllCmd_Executed"/>
</Window.CommandBindings>

Paso dos,

Escribir el código del escuchador en la ventana e código

Private Sub SaveAsCommandBinding_Executed(sender As Object, e As ExecutedRoutedEventArgs)
      'Este ejemplo toca un sonido (por hacer alguna cosa)
      Dim objBeep As New Microsoft.VisualBasic.Devices.Audio
      objBeep.PlaySystemSound(System.Media.SystemSounds.Beep)
End Sub

Paso Tres

Decirle al menú, que cuando se le pulse, llame a este comando para que se ejecute.

<MenuItem Header="Save All (Todo) "  x:Name="MenuArchivoGuardarTodo"
                ToolTip="Guardar todos los documentos"
                Command="{StaticResource SaveAllCmd}"/>

Paso Cuatro

Definir el InputGestureText para que se ejecute el [Command] usando el teclado

Pues no , en este caso ya no hace falta porque las teclas se definieron cuando se define el [RoutedUICommand]. (recuerda que lo hicimos en el paso cero


↑↑↑

Las imágenes del menú

Para incluir una imagen en el menú hay que usar la etiqueta [Icon]

<MenuItem.Icon>
      <Image Width="16" Height
="16"  Stretch="UniformToFill"
             Source="pack://application:,,,/03Vistas_Layer/0302_ImagenesComunes/MenuFile/Save_6530.png" />
</MenuItem.Icon>

Si usas imagenes xaml hay que copiar y pegar el código de la imagen entre las etiquetas

También es conveniente que escojas el icono de 16 puntos.


↑↑↑

A.2.Enlaces

[Para saber mas]
  • Propiedad UIElement.InputBindings Obtiene la colección de enlaces de entrada asociada a este elemento.
  • Clase KeyBinding Enlaza un KeyGesture para un RoutedCommand (u otro ICommand implementación).
    • Key Obtiene o establece la Key de la KeyGesture asociada a esta KeyBinding.
    • Modifiers Obtiene o establece la ModifierKeys de la KeyGesture asociada a esta KeyBinding.
    • Gesture Obtiene o establece el movimiento asociado a este KeyBinding.(Invalida InputBinding.Gesture).
    • Command Obtiene o establece el ICommand asociado a este enlace de entrada.(Heredado de InputBinding).
  • Clase CommandBinding Enlaza un RoutedCommand a los controladores de eventos que implementan el comando.
    • Executed Se produce cuando se ejecuta el comando asociado a este CommandBinding.
    • Command Obtiene o establece el ICommand asociado a este CommandBinding.
    • Clase RoutedUICommand Define un ICommand que se enruta a través del árbol de elementos y contiene una propiedad de texto.
  • Defining MenuItem Shortcuts
[Grupo de documentos]
[Documento Index]
[Documento Start]
[Imprimir el Documento]
© 1997 - - La Güeb de Joaquín
Joaquín Medina Serrano
Ésta página es española

Codificación
Fecha de creación
Última actualización
[HTML5 Desarrollado usando CSS3]