Passer un paramètre en utilisant RelayCommand défini dans le ViewModel (à partir de l'exemple de Josh Smith)

StackOverflow https://stackoverflow.com/questions/810208

Question

Je souhaite transmettre un paramètre défini dans le XAML (View) de mon application à la classe ViewModel à l'aide de RelayCommand. J'ai suivi l'excellent l'excellent article de Josh Smith sur MVVM et ai implémenté le suivant .

Code XAML

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

Code de modèle de vue

  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

J'ai défini un point d'arrêt dans la méthode CommandWithAParameter et j'ai observé que aParameter était défini sur & "Apple &" et non sur & "Orange &". Cela semble évident puisque la méthode CommandWithAParameter est appelée avec la chaîne littérale & "Apple &";

Cependant, en regardant la pile d'exécution, je peux voir que & "Orange &"; le paramètre CommandParameter que j'ai défini dans le code XAML correspond à la valeur de paramètre pour l'implémentation RelayCommand de la méthode d'interface ICommand Execute.

La valeur du paramètre dans la méthode ci-dessous de la pile d'exécution est & "Orange &",

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

Ce que j'essaie de comprendre, c'est comment créer la propriété RelayCommand ACommandWithAParameter de sorte qu'elle puisse appeler la méthode CommandWithAParameter avec le CommandParameter & "Orange &"; défini dans le XAML.

Y a-t-il un moyen de faire cela?

Pourquoi est-ce que je veux faire ça? Partie de & Quot; Localisation à la volée & Quot; Dans mon implémentation particulière, je souhaite créer une RelayCommand SetLanguage pouvant être liée à plusieurs boutons. Je souhaite transmettre l'identificateur de la langue à deux caractères (& "; En &"; & "; Es &"; & "; Ja &"; Etc.) en tant que le CommandParameter et ont qui soit défini pour chaque " set language " bouton défini dans le XAML. Je souhaite éviter de créer une commande SetLanguageToXXX pour chaque langue prenant en charge et de coder en dur l'identificateur de langue à deux caractères dans chaque RelayCommand du ViewModel.

Était-ce utile?

La solution

Je ne comprends pas pourquoi vous avez la complexité supplémentaire de spécifier le lambda en premier lieu. Pourquoi ne pas simplement faire ceci:

if (_aCommandWithAParameter == null)
{           
    _aCommandWithAParameter = new RelayCommand<object>(CommandWithAParameter);
}

private void CommandWithAParameter(object state)
{
    var str = state as string;
}

Autres conseils

Vous passerez le paramètre dans le lambda à la commande comme suit:

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

Rien publié ici auparavant ne fonctionnait pour moi.

Il s'avère que < objet > après RelayCommand !

Cela fonctionne pour moi:

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 vous souhaitez utiliser une méthode CanExecute , utilisez le code suivant:

_okCommand = new RelayCommand<object>(OkCommand_Execute, OkCommand_CanExecute);

private bool OkCommand_CanExecute(object obj) { }

J'essaie juste de vendre mon argument, vérifiez si cela fonctionne ...

http: // mywpf- visu.blogspot.com/2009/12/relay-command-how-to-pass-parameter.html

Voici une solution simple pour le paramètre de commande car je cherchais de l'aide sur le sujet. Je n'ai rien trouvé en ligne qui soit assez simple. La solution suivante fonctionne bien lorsque vous utilisez une commande relay. J'avais quelques hyperliens pour lesquels j'avais besoin d'obtenir la valeur de l'URL sur laquelle on avait cliqué à l'aide du paramètre de commande.

Étape 1: dans votre commande de relais, créez une propriété simple qui contiendra la valeur de l’objet paramètre. Vous pouvez l'appeler parametervalue ou tout autre nom que vous préférez.

public object ParameterValue
{
  get;
  set;
}

Étape 2: dans la méthode Execute de la classe RelayCommand, définissez la valeur ou la propriété créée ci-dessus sur le paramètre de la méthode Execute.

readonly Action<object> m_execute;       // Action to execute

public void Execute(object parameter)
 {
   this.ParameterValue = parameter;
   m_execute(parameter);
 }

Étape 3: Maintenant, lorsque vous pouvez lier le CommandParameter in xaml à n’importe quelle valeur que vous voulez récupérer lorsque la commande est exécutée. exemple:

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

Si vous avez une commande appelée chickenCommand, vous pouvez accéder au paramètre, une fois exécuté: chickenCommand.ParameterValue

J'espère que cela aide quelqu'un. Merci pour toute votre aide précédente.

Je ne peux pas substituer une référence au nom de la méthode à l'expression lamda avec une erreur de compilation. Apparemment, et sans surprise, une référence de nom de méthode non statique ne peut être utilisée à la place d'un lambda. Je le vois à peine comme une "complexité accrue". Les lamdas qui passent constamment ont du sens pour moi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top