example commandmanager c# silverlight mvvm delegates icommand

commandmanager - RelayCommand in C#



mvvm wpf (2)

Estoy aprendiendo MVVM para el desarrollo de C # Silverlight desde

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

y estoy confundido acerca de la clase RelayCommand mencionada en el contexto. El código es:

public class RelayCommand : ICommand { #region Fields readonly Action<object> _execute; readonly Predicate<object> _canExecute; #endregion // Fields #region Constructors public RelayCommand(Action<object> execute) : this(execute, null) { } public RelayCommand(Action<object> execute, Predicate<object> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion // Constructors #region ICommand Members [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _execute(parameter); } #endregion // ICommand Members }

Por lo que realmente no entiendo cómo funciona _execute y _canExecute en este caso. (Soy nuevo en C # e incluso no estoy seguro de qué es Acción y Predicado. Sé que son delegados, pero ¿cuál es la diferencia entre ellos y cómo funcionan?)
Y también, en el programa, no conseguí la línea

add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; }

¿Puede alguien darme una explicación sobre esto, gracias!


Los add / remove son como una propiedad get / set pero para eventos en su lugar. El código de agregado se llamaría cuando

RelayCommandInstance.CanExecuteChanged += MyChangedEventHandler

es ejecutado. El código de eliminación se invoca cuando - = se ejecuta. No se ve mucho esta sintaxis, ya que rara vez se necesita anular el comportamiento predeterminado de agregar / quitar el delegado de la lista de llamadas de eventos.

En este caso, RelayCommand solo está asignando su evento CanExecuteChanged al evento CommandManager.RequerySuggested.


Un RelayCommand requiere dos piezas de información:

  1. Qué código debe ejecutarse cuando se ejecuta el comando (la acción _execute )
  2. Qué código debe ejecutarse para determinar si este comando se puede ejecutar (el predicado _canExecute )

Una Action es un delegado que representa un método que devuelve void . En este caso, la acción _execute toma un parámetro (un object ) y devuelve void .

Un Predicate es un delegado que toma un valor y devuelve un resultado booleano. En este caso, el predicado _canExecute toma un valor de object y devuelve un bool .

Los valores _execute y _canExecute se suministran al RelayCommand cuando se construye porque estas son las partes del comando que son exclusivas para cada comando individual.

En cuanto al evento CanExecuteChanged :

public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } }

Cuando un suscriptor se suscribe al evento, se llama a add y cuando se da de baja, se llama a remove . El evento CanExecuteChanged anterior es solo un evento de paso (es decir, si un suscriptor se suscribe al evento CanExecuteChanged , se suscribe automáticamente al evento CommandManager.RequerySuggested ). Según MSDN , el evento CommandManager.RequerySuggested ...

se produce cuando CommandManager detecta condiciones que pueden cambiar la capacidad de ejecución de un comando.

Creo que lo más probable es que un suscriptor llame al método CanExecute en el RelayCommand cuando este evento se RelayCommand para determinar si el comando todavía se puede ejecutar.