Archivo por meses: febrero 2019

ApplicationCommands, localización u otras historias idiomáticas

Pues eso… si has usado alguna vez los ApplicationCommands en una aplicación WPF sabrás de que te hablo, al menos si has trabajado con el Visual Studio en un idioma diferente al inglés o si tienes una versión de Windows configurada con otro idioma diferente al inglés, que para el caso es lo mismo… o casi…

Si has mirado el enlace de ApplicationCommands sabrá que son comandos para añadir funcionalidad «automática» de Guardar, Abrir, etc. a tus opciones de menús, botones o donde decidas que esos comandos se ejecuten.

Lo primero con lo que nos encontramos al añadir uno de esos comandos, por ejemplo el comando de Guardar (Save) a un elemento de menú (MenuItem) es que esa opción no estará habilitada, siempre se mostrará inhabilitada… ya que ese comando de aplicación necesita saber si la opción debe estar disponible o no…

Vayamos por pasos, así que… añadimos primero un menú Archivo a una aplicación de WPF definiendo un menú principal y la opción de Guardar, tal como vemos en el siguiente código XAML.

<Menu Grid.Row="0" Grid.Column="0" 
      Grid.ColumnSpan="2" Background="AliceBlue">
    <MenuItem Header="_Archivo" ToolTip="Abrir, Guardar, Salir">
        <MenuItem x:Name="mnuGuardar" Header="_Guardar" 
                  Command="ApplicationCommands.Save"
                  ToolTip="Guardar (Ctrl+S o Ctrl+G)"
                  Click="MnuGuardar_Click">
            <MenuItem.Icon>
                <Image Source="Images\Save_16x.png" />
            </MenuItem.Icon>
        </MenuItem>
</Menu>

En modo edición este menú se mostrará más o menos como vemos en la figura 1, en la que hay más opciones de ese menú de archivo que las mostradas en el código anterior, pero solo debes prestar atención al menú Guardar.

Figura 1. El menú Guardar usando ApplicationCommands.Save en modo diseño

Fíjate que el texto Ctrl+S lo ha añadido automáticamente. Ese sería el acceso de teclado rápido para el idioma inglés.

Decirte que esa captura la he tomando con el Visual Studio 2017 (lo mismo mostraría el VS 2019) con el idioma inglés.

Si iniciamos la aplicación, veremos dos cosas interesantes… al menos una de ellas es interesante, la otra… pues… cosas de la localización automática según el idioma de Windows, que en mi caso es el Windows 10 con el paquete de idiomas en español.

Si te fijas en la figura 2 verás que el comando Guardar está deshabilitado y la segunda cosa a destacar es que ahora no se muestra Ctrl+S si no Ctrl+G que es el equivalente a Guardar en el idioma español.

Figura 2.

¡Guay! o no… Ahora verás porque puede no ser cool (guay).

Veamos qué ocurre si el Visual Studio lo usamos con el idioma en español… pues… tal como puedes ver en la figura 3, se muestra Ctrl+G en lugar de Ctrl+S.

Figura 3. Usando el Visual Studio con el idioma en español.

Aquí vuelve a mostrar Ctrl+G tanto en modo diseño como en ejecución.

Pero lo curioso de todo esto es que ¡el acceso de teclado Ctrl+G no funciona!

El que funciona es Ctrl+S está en el idioma que esté el Visual Studio y el Windows. Pues sí, como te lo cuento…

Solucionando entuertos…

Vayamos arreglando las cosas… para empezar el que ese menú esté inaccesible (deshabilitado) es porque no le hemos dicho que se habilite.

Esto lo arreglamos añadiendo una definición en el código XAML , concretamente en la sección <Window.CommandBindings> tal como vemos en el siguiente código XAML, que estará después de la definición de la ventana.

<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Save" 
                    CanExecute="CommandGuardar_CanExecute"
                    Executed="CommandGuardar_Executed" />
    

</Window.CommandBindings>

Con ese código le estamos indicando que tenemos dos métodos definidos, el primero asignado a la propiedad CanExecute que es el que indica si debe estar habilitado o no ese comando, el segundo (el asignado a la propiedad Execute) es lo que debe hacer si se puede ejecutar el comando (el usuario puede pulsar en la opción del menú o usar el acceso rápido del teclado).

El siguiente código (para Visual Basic) te muestra lo que yo he hecho en esos dos comandos.

' Comando guardar
Private Sub CommandGuardar_CanExecute(sender As Object, 
                                       e As CanExecuteRoutedEventArgs)
    If IsLoaded = False Then Return
    e.CanExecute = rtbModificado
End Sub

Private Sub CommandGuardar_Executed(sender As Object, 
                                     e As ExecutedRoutedEventArgs)
    mnuGuardar.RaiseEvent(New RoutedEventArgs(MenuItem.ClickEvent))
End Sub

En el método asociado al comando CanExecute le indicamos cuando habilitar la opción, que será cuando la ventana esté cargada y se podrá ejecutar si el valor de rtbModificado es TRUE. Esa variable indicará si el texto se ha modificado.

Por otro lado, el comando Execute contiene una llamada al método que se encarga de llamar al método asociado con el evento Click del MenuItem. Fíjate que no se pone el nombre del método de evento, de cuál es ya se encargará el compilador o motor de ejecución de averiguarlo.

Ya tenemos una parte del problema resuelta. Creo que la más importante, ya que si el menú no está habilitado, pues… el resto de problemas dejan de serlos Winking smile

Ahora veamos cómo dar la funcionalidad de que ese comando se ejecute si el usuario que utiliza nuestra aplicación en un entorno con el idioma español pulsa Ctrl+G (recuerda que te dije que aunque se muestra Ctrl+G, el acceso rápido sigue siendo Ctrl+S).

Lo que necesitamos es añadir funcionalidad a la pulsación de teclas Ctrl+G y que esté relacionado con el comando guardar.

Decirte que no vale (o al menos no vale la pena) intentar interceptar en la aplicación esa combinación de teclas, ya que tenemos una forma más fácil de hacerlo… al menos si se sabe cómo hacerlo… y ya sabes… aquí esta el Guille para decirte cómo… jejeje.

En el código XAML de la definición de la ventana, creamos una sección llamada <Window.InputBindings> (la podemos poner detrás de la que creamos antes para definir los comandos). Y añadimos lo siguiente:

<Window.InputBindings>
    <!-- podemos indicar las teclas a usar con los comandos definidos 
         aunque no estén asociados a ningún control ni MenuItem -->

    <!-- aunque muestra Ctrl+G en realidad usa Ctrl+S por eso defino Ctrl+G -->
    <KeyBinding Command="ApplicationCommands.Save" Key="G" Modifiers="Ctrl" />


</Window.InputBindings>

Y eso es todo, por supuesto la combinación predeterminada (Ctrl+S) sigue funcionando.

Decirte que no todas las combinaciones que pongas ahí se tendrán en cuenta, hay algunas combinaciones que ya están asociadas a otros comandos que no podrás usar.

Además me ha ocurrido que hay ciertas combinaciones de teclas que tampoco se pueden usar y aparentemente no están asociadas a nada… (por ejemplo Ctrl+Shift+S que en Visual Studio es Guardar todo, pero en mi aplicación… ¿qué comando es?). En fin… misterios por resolver I don't know smile

Nos vemos.
Guillermo

Ya están los foros en modo SOLO-LECTURA

Pues eso… ya es 1 de febrero de 2019 y como te comenté hace unos días, los foros (no el blog ni el sitio) ya está en modo SOLO-LECTURA, es decir, se podrán seguir viendo los mensajes que haya, pero no se podrán hacer nuevas consultas, ni responder a las existentes, ni tampoco editarlas. aunque sí se podrán marcar los mensajes como que responden a la pregunta o consulta realizada, pero si quieres que te diga la verdad, dudo que muchos entren nuevamente en los foros para marcar las respuestas… si no lo hicieron en su día… no lo van a hacer después de algún tiempo… Winking smile

Desde el 1 de febrero de 2019 los foros del Guille son de solo lectura

Si eres moderador de mis foros o estás en la categoría de MVP (antes debes estar registrado en los foros) podrás seguir modificando, respondiendo o escribiendo nuevos mensajes.

Los usuarios «normales» si pulsan en el botón de responder, modificar o nuevo, los mandará a la página de aviso de que está cerrado.

Por cierto, si quieres colaborar comprobando las respuestas a los mensajes para ver si responden a la pregunta, coméntalo en este mismo post y así los foros tendrán un valor añadido. Gracias.

Y esto es todo por ahora…. en marzo nuevos cambios… espero…

Nos vemos.
Guillermo