wpf - definicion - comandos de internet
Ejemplo de patrĂ³n de comando personalizado de WPF (4)
¡Ah, ja! Una pregunta que puedo responder! En primer lugar, debo mencionar que personalmente he encontrado que es más fácil definir y conectar comandos en código que en XAML. Me permite conectar los manejadores para los comandos un poco más flexiblemente de lo que lo hace un enfoque XAML.
Debería averiguar qué comandos quiere tener y con qué se relacionan. En mi aplicación, actualmente tengo una clase para definir comandos de aplicaciones importantes, como por ejemplo:
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 el código en su totalidad, usar un enfoque de solo código para Commands me permite poner 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 puede incluso ser compartido con otros Comandos sin que yo tenga que repetirlo por todos lados.
Una vez que haya definido los comandos de esta manera, puede agregarlos a cualquier pieza de UI. A continuación, una vez que la ventana se ha cargado, 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 comando. El parámetro que se pasa es la Ventana en sí misma, por lo que el código anterior sabe qué Ventana probar y 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 tengo controladores de eventos para los eventos WindowClosing y WindowClosed, te recomiendo que hagas la implementación de comandos tan pequeña y genérica como sea posible. Como en este caso, no intenté poner un código que intente detener el cierre de la ventana si hay datos no guardados, guardé ese código firmemente dentro del evento WindowClosing.
Avíseme si tiene alguna pregunta de seguimiento. :)
He hecho algo de programación de WPF y una cosa que nunca obtuve fue el patrón de comando. Todos los ejemplos parecen estar integrados, editar, cortar, pegar. ¿Alguien tiene un ejemplo o sugerencia de las mejores prácticas para los comandos personalizados?
En la edición de septiembre de 2008 de la revista MSDN, Brian Noyes tiene un excelente artículo sobre el RoutedCommand / RoutedEvents !!!
Aquí está el enlace: 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. Digamos que tiene varias clases y todas las UI tienen comandos que nunca fueron deshabilitados, ¡tendría que escribir un método ''CanAlwaysExecute'' para cada ventana o UserControl! Eso no es muy seco
Después de leer varios blogs y probar varias cosas, tomé la decisión de hacer XAML puramente sobre apariencia, estilos, animación y desencadenantes. Toda mi conexión de manejadores de eventos y comando ahora está en el código subyacente. :)
Otro inconveniente es el enlace de entrada, para que puedan capturarse, el foco debe estar en el objeto que contiene los enlaces de entrada. Por ejemplo, para tener un atajo que puede usar en cualquier momento (por ejemplo, F1 para abrir la ayuda), ese enlace de entrada debe establecerse en el objeto Ventana, ya que siempre tiene foco cuando su aplicación está Activa. Usar el método de código debería facilitar eso, incluso cuando comiences a utilizar UserControls que podrían querer agregar enlaces de entrada a su ventana principal.
Redacté un blog sobre varios recursos en Comandos de WPF junto con un ejemplo el año pasado en http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx
Pegando aquí:
Capítulo de muestra de Adam Nathan sobre importantes conceptos nuevos en WPF: Comandos
Artículo de MSDN: El patrón de comando en WPF
Keyvan Nayyeri: Cómo agregar comandos al control WPF personalizado
Ian Griffiths: Entrada de Avalon, Comandos y Manejadores
MSDN Library: descripción general
Biblioteca MSDN: Clase CommandBinding
MSDN Library: temas de procedimientos de entrada y comandos
MSDN Library: EditingCommands Class
MSDN Library: MediaCommands Class
MSDN Library: Clase ApplicationCommands
MSDN Library: NavigationCommands Class
MSDN Library: ComponentCommands Class
También está enterrado en las muestras WPF SDK, hay una buena muestra en la edición RichTextBox que he extendido. Puede encontrarlo aquí: RichTextEditor.zip