Pregunta

Por lo que entiendo, el objetivo del patrón de Comando es ayudar a separar la interacción de la interfaz de usuario de la lógica de la aplicación. Con comandos implementados correctamente, haga clic en " Imprimir " el elemento del menú puede generar una cadena de interacción como esta:

(button) ---click executes command----> (command) ---calls Print() in app logic ---> (logic)

Esto lo alienta a separar la interfaz de usuario de la lógica de la aplicación.

He estado mirando los comandos de WPF, y en su mayor parte veo cómo han implementado este patrón. Sin embargo, creo que, hasta cierto punto, han complicado el patrón de Comando y han logrado implementarlo de tal manera que se desaconseja separar la IU de la lógica de la aplicación.

Por ejemplo, considere esta simple ventana de WPF que tiene un botón para pegar texto en el cuadro de texto:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Paste"
                        Executed="CommandBinding_Executed"/>
    </Window.CommandBindings>
    <StackPanel>
        <TextBox x:Name="txtData" />
        <Button Command="Paste" Content="Paste" />
    </StackPanel>
</Window>

Aquí está el código subyacente:

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ApplicationCommands.Paste.Execute(null, txtData);
        }
    }
} 

¿Qué obtuve del comando? Me parece que podría haber puesto fácilmente el código del controlador de eventos de enlace de comandos en el evento Click del botón. Claro, ahora puedo asociar múltiples elementos de la interfaz de usuario con el comando Pegar y solo tengo que usar un controlador de eventos, pero ¿qué pasa si quiero pegar en varios cuadros de texto diferentes? Tendría que hacer que la lógica del controlador de eventos sea más complicada o escribir más controladores de eventos. Ahora, siento que tengo esto:

(button) ---executes Routed Command---> (Window) ---executes command binding----(command binding)
(logic) <---calls application logic--- (event handler) <-----raises event --------------|

¿Qué me estoy perdiendo aquí? Me parece una capa adicional de indirección.

¿Fue útil?

Solución

Además de las cosas ya mencionadas, lo que ha olvidado en su ejemplo específico de Paste son las propiedades CommandTarget y CommandParameter. Para Pegar, puede especificar un TextBox configurando como CommandTarget.

Estas propiedades son absolutamente esenciales cuando se quiere usar el mismo RoutedCommand desde diferentes controles. Le permiten proporcionar al controlador Ejecutado información sobre el contexto en el que se invoca el comando.

Otros consejos

Puede ser conceptos confusos.

La interfaz ICommand admite el patrón de comando. Eso le permite abstraer las acciones del usuario en una clase reutilizable.

Los

comandos enrutados son una implementación particular de ICommand que busca controladores en el árbol visual. Son particularmente útiles para comandos que pueden ser implementados por muchos controles diferentes, y desea que el control actual lo maneje. Piensa en copiar / pegar. Podría haber una gran cantidad de controles que podrían manejarlo, pero al usar el comando enrutado, el sistema de comando enrutado encontrará automáticamente el control correcto para manejar el comando en función del enfoque.

Me gustaría usar los comandos RoutedCommands y RoutedUICommands al crear controles. Por ejemplo, TextBox implementa el UndoCommand para usted y la fuente de entrada ya está vinculada a Ctrl + Z . Sin embargo, al crear modelos de vista, mi preferencia es un ICommand personalizado con implementaciones internas de Execute y CanExecute. El DelegateCommand proporciona esto en Prism. Esto permite que el diseñador de view / xaml solo se preocupe por el comando y no por los controladores Execute / CanExecute correctos para usar. Esto permitiría un modelo de vista más expresivo.

ps. Los comandos de delegado aún no funcionan (elegantemente) con InputBindings. ¿Puede alguien en Microsoft arreglar esto, por favor!

Pueden ser excesivos para algunas cosas, pero obtienes algunos buenos beneficios como CanExecute que puede habilitar / deshabilitar automáticamente botones / elementos de menú cuando el comando no está disponible (como no hay texto seleccionado, etc.). También puedes hacer cosas de comando en Blend, sin usar ningún código, lo cual es genial para los diseñadores.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top