Pregunta

Hice algo de programación en WPF y una cosa que nunca obtuve fue el patrón de comando.Cada ejemplo parece ser para los integrados, editar, cortar, pegar.¿Alguien tiene un ejemplo o sugerencia de mejores prácticas para comandos personalizados?

¿Fue útil?

Solución

¡Ah, ja!¡Una pregunta que puedo responder!En primer lugar, debo mencionar que personalmente me ha resultado más fácil definir y conectar comandos en código que en XAML.Me permite conectar los controladores de los comandos de forma un poco más flexible que un enfoque totalmente XAML.

Debes determinar qué comandos quieres tener y con qué se relacionan.En mi aplicación, actualmente tengo una clase para definir comandos importantes de la aplicación como este:

public static class CommandBank
{
  /// Command definition for Closing a window
  public static RoutedUICommand CloseWindow { get; private set; }

  /// Static private constructor, sets up all application wide commands.
  static CommandBank()
  {
    CloseWindow = new RoutedUICommand();
    CloseWindow.InputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt));
    // ...
  }

Ahora, como quería mantener todo el código junto, usar un enfoque de solo código para los Comandos me permite colocar los siguientes métodos en la clase anterior:

/// Closes the window provided as a parameter
public static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e)
{
  ((Window)e.Parameter).Close();
}

/// Allows a Command to execute if the CommandParameter is not a null value
public static void CanExecuteIfParameterIsNotNull(object sender, CanExecuteRoutedEventArgs e)
{
  e.CanExecute = e.Parameter != null;
  e.Handled = true;
}

El segundo método incluso se puede compartir con otros comandos sin que tenga que repetirlo por todos lados.

Una vez que haya definido comandos como este, puede agregarlos a cualquier parte de la interfaz de usuario.A continuación, una vez que se ha cargado la ventana, agrego enlaces de comandos tanto a la ventana como a MenuItem y luego agrego un enlace de entrada a la ventana usando un bucle para hacer esto para todos los enlaces de comandos.El parámetro que se pasa es la propia ventana, por lo que el código anterior sabe qué ventana intentar cerrar.

public partial class SimpleWindow : Window
{
  private void WindowLoaded(object sender, RoutedEventArgs e)
  {
    // ...
    this.CommandBindings.Add(
      new CommandBinding(
        CommandBank.CloseWindow,
        CommandBank.CloseWindowExecute,
        CommandBank.CanExecuteIfParameterIsNotNull));

    foreach (CommandBinding binding in this.CommandBindings)
    {
       RoutedCommand command = (RoutedCommand)binding.Command;
       if (command.InputGestures.Count > 0)
       {
         foreach (InputGesture gesture in command.InputGestures)
         {
           var iBind = new InputBinding(command, gesture);
           iBind.CommandParameter = this;
           this.InputBindings.Add(iBind);
         }
       }
    }

    // menuItemExit is defined in XAML
    menuItemExit.Command = CommandBank.CloseWindow;
    menuItemExit.CommandParameter = this;
    // ...
  }

  // ....
}

Luego también tendré controladores de eventos para los eventos WindowClosing y WindowClosed. Le recomiendo que haga que la implementación real de los comandos sea lo más pequeña y genérica posible.Como en este caso, no intenté poner código que intente detener el cierre de la ventana si hay datos no guardados, mantuve ese código firmemente dentro del evento WindowClosing.

Déjame saber si tienes alguna pregunta de seguimiento.:)

Otros consejos

En la edición de septiembre de 2008 de la revista MSDN, Brian Noyes tiene un excelente artículo sobre RoutedCommand/RoutedEvents!!!

Aqui esta el link:http://msdn.microsoft.com/en-us/magazine/cc785480.aspx

Lo que pasa con XAML es que está bien para programas "simples", pero lamentablemente no funciona bien cuando quieres hacer cosas como compartir funciones.Supongamos que tiene varias clases y UI, todas las cuales tienen comandos que nunca se deshabilitaron, ¡tendría que escribir un método 'CanAlwaysExecute' para cada ventana o control de usuario!Eso simplemente no es muy SECO.

Después de leer varios blogs y probar varias cosas, tomé la decisión de hacer XAML exclusivamente sobre apariencia, estilos, animación y activadores.Toda mi conexión de controladores de eventos y comandos ahora está en el código subyacente.:)

Otro problema, por cierto, es el enlace de entrada. Para que se detecten, el foco debe estar en el objeto que contiene los enlaces de entrada.Por ejemplo, para tener un atajo que pueda usar en cualquier momento (por ejemplo, F1 para abrir la ayuda), ese enlace de entrada debe configurarse en el objeto Ventana, ya que siempre tiene foco cuando su aplicación está activa.Usar el método de código debería hacerlo más fácil, incluso cuando comience a usar UserControls que deseen agregar enlaces de entrada a su ventana principal.

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