commandmanager - command mvvm c#
Por qué RelayCommand (2)
La ventaja de utilizar el comando de retransmisión es que puede vincular comandos directamente a ViewModels. Mediante el uso de comandos de tal manera que evite escribir código en el codebehind de vistas.
Al usar comandos de retransmisión, deberá proporcionar dos métodos. El primero proporciona un valor si el comando se puede ejecutar (por ejemplo, "CanExecuteSave"), mientras que el otro será responsable de ejecutar el comando ("ExecuteSave").
He estado programando mucho en WPF últimamente, pero mi View y ViewModel no están separados en este momento. Bueno, es parcialmente Todas mis vinculaciones relacionadas con texto en cuadros de texto, contenido para etiquetas, listas en cuadrículas de datos, ... están hechas por propiedades regulares con un evento NotifyPropertyChanged en ellas.
Todos mis eventos para manejar clics de botón o cambiar texto se hacen vinculando los eventos. Ahora, quería empezar a trabajar con comandos y encontré este artículo: http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute . Tiene una explicación de cómo configurar MVVM, pero estoy confundido con el RelayCommand
.
¿Qué trabajo hace? ¿Es utilizable para todos los comandos en mi forma? ¿Cómo desactivo el botón cuando (a) ciertos cuadros de texto no se completan?
EDIT 1:
Una buena explicación para "¿Es utilizable para todos los comandos en mi forma?" se responde aquí: https://stackoverflow.com/a/22286816/3357699
Aquí está el código que tengo hasta ahora: https://stackoverflow.com/a/22289358/3357699
Los comandos se utilizan para separar la semántica y el objeto que invoca un comando de la lógica que ejecuta el comando, es decir, separa el componente UI de la lógica que debe ejecutarse al invocar el comando. Por lo tanto, puede probar la lógica de negocios por separado utilizando casos de prueba y también su código de UI está ligeramente acoplado a la lógica de negocios.
Ahora, dicho esto, vamos a elegir sus preguntas una por una:
¿Qué trabajo hace?
He agregado los detalles arriba. Espero que despeje el uso de comandos.
¿Es utilizable para todos los comandos en mi forma?
Algunos controles expusieron a Command DependenProperty como Button, MenuItem, etc. que tienen algún evento predeterminado registrado en él. Para el evento Button''s Click
. Por lo tanto, si enlaza ICommand
declarado en ViewModel con Command DP de Button, se invocará siempre que se haga clic en el botón.
Para otros eventos, puede vincular usando Interactivity triggers
. Consulte here el ejemplo de cómo usarlos para enlazar a ICommand
en ViewModel.
¿Cómo desactivo el botón cuando (a) ciertos cuadros de texto no se completan?
El enlace que publicó no proporciona la implementación completa de RelayCommand
. Carece del constructor sobrecargado para establecer el predicado CanExecute
que desempeña un papel clave en habilitar / deshabilitar el control de UI al que está CanExecute
su comando.
Enlazar TextBoxes con algunas propiedades en ViewModel y en CanExecute
delegate devuelve falso si alguna de las propiedades binded es nula o está vacía, lo que deshabilita automáticamente el control al que está vinculado el comando.
Implementación completa de RelayCommand
:
public class RelayCommand<T> : ICommand
{
#region Fields
readonly Action<T> _execute = null;
readonly Predicate<T> _canExecute = null;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
/// </summary>
/// <param name="execute">Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate.</param>
/// <remarks><seealso cref="CanExecute"/> will always return true.</remarks>
public RelayCommand(Action<T> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<T> execute, Predicate<T> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region ICommand Members
///<summary>
///Defines the method that determines whether the command can execute in its current state.
///</summary>
///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
///<returns>
///true if this command can be executed; otherwise, false.
///</returns>
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute((T)parameter);
}
///<summary>
///Occurs when changes occur that affect whether or not the command should execute.
///</summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
///<summary>
///Defines the method to be called when the command is invoked.
///</summary>
///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param>
public void Execute(object parameter)
{
_execute((T)parameter);
}
#endregion
}