Passando un parametro usando RelayCommand definito nel ViewModel (dall'esempio di Josh Smith)

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

Domanda

Vorrei passare un parametro definito in XAML (View) della mia applicazione alla classe ViewModel usando RelayCommand. Ho seguito l'eccellente articolo di Josh Smith su MVVM e ho implementato quanto segue .

Codice XAML

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

Codice 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

Ho impostato un punto di interruzione nel metodo CommandWithAParameter e ho osservato che aParameter era impostato su " Apple " ;, e non " Orange " ;. Ciò sembra ovvio poiché il metodo CommandWithAParameter viene chiamato con la stringa letterale & Quot; Apple & Quot ;.

Tuttavia, guardando lo stack di esecuzione, posso vedere che " Orange " ;, il CommandParameter che ho impostato in XAML è il valore del parametro per l'implementazione RelayCommand del metodo dell'interfaccia ICommand Execute.

Questo è il valore del parametro nel metodo seguente dello stack di esecuzione è " Orange " ;,

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

Quello che sto cercando di capire è come creare la proprietà RelayCommand ACommandWithAParameter in modo tale da poter chiamare il metodo CommandWithAParameter con CommandParameter " Orange " definito in XAML.

C'è un modo per farlo?

Perché voglio farlo? Parte di & Quot; Localizzazione al volo & Quot; Nella mia particolare implementazione voglio creare un SetLanguage RelayCommand che può essere associato a più pulsanti. Vorrei passare l'identificatore del linguaggio a due caratteri (& Quot; en & Quot ;, & Quot; es & Quot ;, & Quot; ja & Quot ;, ecc.) Come CommandParameter e devono essere definiti per ogni " imposta la lingua " pulsante definito in XAML. Voglio evitare di dover creare un comando SetLanguageToXXX per ogni lingua che supporta e codifica hard l'identificatore della lingua dei due caratteri in ciascun comando Relay nel ViewModel.

È stato utile?

Soluzione

Non capisco perché tu abbia l'ulteriore complessità di specificare la lambda in primo luogo. Perché non farlo semplicemente:

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

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

Altri suggerimenti

Passerai il parametro in lambda al comando in questo modo:

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

Nulla pubblicato qui prima ha funzionato per me.

Si scopre che a tutte le risposte manca <object> dopo RelayCommand!

Questo funziona per me:

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;
}

Se si desidera utilizzare un metodo CanExecute, utilizzare il seguente codice:

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

private bool OkCommand_CanExecute(object obj) { }

Sto solo cercando di vendere il mio punto, controlla se funziona ...

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

Ecco una semplice soluzione per il parametro di comando mentre cercavo aiuto sull'argomento. Non sono riuscito a trovare nulla online abbastanza semplice. La seguente soluzione funziona bene quando si utilizza un comando a relè. Avevo alcuni collegamenti ipertestuali per i quali avevo bisogno di ottenere il valore url che è stato cliccato usando il parametro command.

Passaggio 1: nel comando relay, creare una proprietà semplice che conterrà il valore dell'oggetto parametro. Potresti chiamarlo parametervalue o qualsiasi nome tu preferisca.

public object ParameterValue
{
  get;
  set;
}

Passaggio 2: nel metodo Execute della classe RelayCommand, imposta il valore o la proprietà creata sopra sul parametro dal metodo Execute.

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

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

Passaggio 3: ora quando è possibile associare CommandParameter in xaml a qualsiasi valore che si desidera recuperare quando viene eseguito il comando. esempio:

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

Se hai un comando chiamato chickenCommand, una volta eseguito potresti accedere al parametro: chickenCommand.ParameterValue

Spero che questo aiuti qualcuno. Grazie per tutto il tuo precedente aiuto.

Non posso sostituire un riferimento al nome del metodo per l'espressione lamda con un errore di compilazione. Apparentemente, e non sorprendentemente, un riferimento al nome del metodo non statico non può essere usato al posto di una lambda. Non lo vedo quasi come & Quot; complessità aggiunta & Quot ;. Il passaggio coerente dei lama ha senso per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top