2009-01-21 12 views
5

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 adecuadamente, un clic en un elemento de menú "Imprimir" podría dar lugar a una cadena de interacción de esta manera:¿Los comandos enrutados de WPF resuelven un problema o lo empeoran?

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

Esto le anima a separar la interfaz de usuario de la lógica de la aplicación.

He estado viendo los comandos de WPF, y en su mayor parte veo cómo han implementado este patrón. Sin embargo, creo que hasta cierto punto tienen el complicado patrón de comando y se las han arreglado para implementarlo de tal manera que no se recomienda separar la interfaz de usuario de la lógica de la aplicación.

Por ejemplo, considere esto 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é gano con el ¿mando? 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 varios elementos de la interfaz de usuario con el comando Pegar y solo tengo que usar el controlador de eventos, pero ¿qué sucede si quiero pegar en varios cuadros de texto diferentes? Tendría que complicar la lógica del controlador de eventos o escribir más manejadores de eventos. Así que 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 falta aquí? Parece una capa extra de indirección para mí.

Respuesta

2

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

Estas propiedades son absolutamente esenciales cuando se quiere utilizar el mismo RoutedCommand desde diferentes controles. Permiten darle al controlador ejecutado cierta información sobre el contexto en el que se invoca el comando.

+0

Leí un capítulo de un libro sobre comandos anoche y encontré esta información, luego me sentí como una droga. – OwenP

0

Pueden ser exagerados para algunas cosas, pero obtienes algunos beneficios agradables como CanExecute que puede activar/desactivar automáticamente botones/elementos de menú cuando el comando no está disponible (como sin 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.

3

Puede confundir conceptos.

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 a través del árbol visual para los controladores. Son particularmente útiles para comandos que pueden ser implementados por muchos controles diferentes, y usted quiere que el control actual lo maneje. Piensa copiar/pegar. Podría haber un montón de controles que podrían manejarlo, pero al usar el comando enrutado, el sistema de comando enrutado automáticamente encontrará el control correcto para manejar el comando en función del enfoque.

2

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

ps. Los comandos delegados aún no funcionan (elegantemente) con InputBindings. ¿Puede alguien en Microsoft arreglar esto por favor?

Cuestiones relacionadas