example commandmanager .net wpf data-binding mvvm lambda

.net - commandmanager - icommand wpf



Pasar un parĂ¡metro usando RelayCommand definido en ViewModel(del ejemplo de Josh Smith) (6)

Me gustaría pasar un parámetro definido en el XAML (Vista) de mi aplicación a la clase ViewModel usando el RelayCommand. Seguí el excelente artículo de Josh Smith sobre MVVM y he implementado lo siguiente.

Código XAML

<Button Command="{Binding Path=ACommandWithAParameter}" CommandParameter="Orange" HorizontalAlignment="Left" Style="{DynamicResource SimpleButton}" VerticalAlignment="Top" Content="Button"/>

Código de ViewModel

public RelayCommand _aCommandWithAParameter; /// <summary> /// Returns a command with a parameter /// </summary> public RelayCommand ACommandWithAParameter { get { if (_aCommandWithAParameter == null) { _aCommandWithAParameter = new RelayCommand( param => this.CommandWithAParameter("Apple") ); } return _aCommandWithAParameter; } } public void CommandWithAParameter(String aParameter) { String theParameter = aParameter; } #endregion

Establecí un punto de interrupción en el método CommandWithAParameter y observé que aParameter se estableció en "Apple" y no en "Orange". Esto parece obvio ya que se llama al método CommandWithAParameter con la cadena literal "Apple".

Sin embargo, al buscar la pila de ejecución, puedo ver que "Naranja", el parámetro de comando I establecido en el XAML es el valor del parámetro para la implementación de RelayCommand del método de interfaz Ejecución ICommand.

Ese es el valor del parámetro en el siguiente método de la pila de ejecución es "Naranja",

public void Execute(object parameter) { _execute(parameter); }

Lo que estoy tratando de averiguar es cómo crear la propiedad RelayCommand ACommandWithAParameter de modo que pueda llamar al método CommandWithAParameter con el Parámetro de comando "Naranja" definido en el XAML.

¿Hay alguna forma de hacer esto?

¿Por qué quiero hacer esto? Parte de la "Localización On The Fly" En mi implementación particular, quiero crear un SetLanguage RelayCommand que pueda vincularse a múltiples botones. Me gustaría pasar el identificador de dos caracteres del lenguaje ("en", "es", "ja", etc.) como el parámetro de comando y tenerlo definido para cada botón de "establecer idioma" definido en el XAML. Quiero evitar tener que crear un comando SetLanguageToXXX para cada idioma que admita y codifique el identificador de idioma de dos caracteres en cada RelayCommand en ViewModel.


Aquí hay una solución simple para el parámetro de comando ya que estaba buscando ayuda sobre el tema. No pude encontrar nada en línea que fuera lo suficientemente simple. La siguiente solución funciona bien cuando está utilizando un comando de retransmisión. Tenía algunos hipervínculos para los que necesitaba obtener el valor de URL en el que se hizo clic con el parámetro de comando.

Paso 1: en su comando de retransmisión, cree una propiedad simple que contendrá el valor del objeto del parámetro. Podría llamarlo parametervalue o cualquier nombre que prefiera.

public object ParameterValue { get; set; }

Paso 2: en el método de ejecución de la clase RelayCommand, establezca el valor o la propiedad creada anteriormente en el parámetro del método Execute.

readonly Action<object> m_execute; // Action to execute public void Execute(object parameter) { this.ParameterValue = parameter; m_execute(parameter); }

Paso 3: Ahora cuando puede vincular CommandParameter en xaml a cualquier valor que desee recuperar cuando se ejecuta el comando. ejemplo:

<TextBlock> <Hyperlink Command="{Binding Path=NavigateUrlCmd}" CommandParameter="{Binding ElementName=tbwebsite, Path=Text}"> <TextBlock Name="tbwebsite" Text="{Binding Path=website}"/> </Hyperlink> </TextBlock>

Si tiene un comando llamado chickenCommand, cuando se ejecuta puede acceder al parámetro: chickenCommand.ParameterValue

Espero que esto ayude a alguien. Gracias por toda tu ayuda previa.


Nada publicado aquí antes funcionó para mí.

Resulta que a todas las respuestas les falta el <object> después de RelayCommand .

Esto funciona para mí:

public RelayCommand<object> OKCommand { get { if (_okCommand == null) _okCommand = new RelayCommand<object>(OkCommand_Execute); return _okCommand; } } private RelayCommand<object> _okCommand = null; private void OkCommand_Execute(object obj) { Result = true; }

Si desea utilizar un método CanExecute , use el siguiente código:

_okCommand = new RelayCommand<object>(OkCommand_Execute, OkCommand_CanExecute); private bool OkCommand_CanExecute(object obj) { }


No entiendo por qué tienes la complejidad adicional de especificar el lambda en primer lugar. ¿Por qué no solo hacer esto?

if (_aCommandWithAParameter == null) { _aCommandWithAParameter = new RelayCommand<object>(CommandWithAParameter); } private void CommandWithAParameter(object state) { var str = state as string; }


No puedo sustituir una referencia al nombre del método para la expresión lamda con un error de compilación. Aparentemente, y de ninguna manera sorprendentemente, no se puede usar una referencia de nombre de método no estático en lugar de una lambda. Apenas lo veo como una "complejidad añadida". Pasar constantemente lamdas tiene sentido para mí.


Pasarás el param en la lambda al comando así:

if (_aCommandWithAParameter == null) { _aCommandWithAParameter = new RelayCommand( param => this.CommandWithAParameter(param) ); }