Passando um parâmetro usando RelrayCommand definido no ViewModel (do exemplo de Josh Smith)

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

Pergunta

Gostaria de passar um parâmetro definido no XAML (visualização) do meu aplicativo para a classe ViewModel usando o RelrayCommand. eu segui O excelente artigo de Josh Smith sobre MVVM e implementaram o seguinte.

Código XAML

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

Código do 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

Definei um ponto de interrupção no método CommandWitHaparameter e observei que o aparameter estava definido como "Apple", e não "laranja". Isso parece óbvio, pois o comando do métodoWitHaparameter está sendo chamado com a string literal "Apple".

No entanto, procurando a pilha de execução, posso ver que "laranja", o comandoparameter que eu definir no XAML é o valor do parâmetro para o retrayCommand implemenação do método de interface de execução do ICOMMAND.

Esse é o valor do parâmetro no método abaixo da pilha de execução é "laranja",

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

O que estou tentando descobrir é como criar a propriedade RelrayCommand AcommandWithaParameter, de modo que possa chamar o método de comandoWitHaparameter com o comandoparameter de "laranja" definido no XAML.

Existe uma maneira de fazer isso?

Por que eu quero fazer isso? Parte de "On the Fly Localization" Na minha implementação específica, quero criar um relógio SetLanguage que possa estar vinculado a vários botões. Eu gostaria de passar o identificador de dois caracteres ("en", "es", "ja", etc) como o CommandParameter e ter isso é definido para cada botão "Set Language" definido no XAML. Quero evitar criar um comando setLanguageToxxx para cada idioma que suporta e codificando o identificador de dois caracteres em cada relaycommand no ViewModel.

Foi útil?

Solução

Não entendo por que você tem a complexidade extra de especificar o Lambda em primeiro lugar. Por que não fazer isso:

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

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

Outras dicas

Você passará o param no lambda para o comando assim:

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

Nada postado aqui antes trabalhou para mim.

Acontece que todas as respostas estão perdendo o <object> depois RelayCommand!

Isso funciona para mim:

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 você quiser usar umCanExecute Método, use o seguinte código:

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

private bool OkCommand_CanExecute(object obj) { }

Estou apenas tentando vender meu ponto, verifique se isso funciona ...

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

Aqui está uma solução simples para o CommandParameter, pois eu estava procurando ajuda sobre o assunto. Não consegui encontrar nada online que tenha sido bastante simples. A solução a seguir funciona bem quando você está usando um relayCommand. Eu tinha alguns hiperlinks para os quais precisava obter o valor da URL que foi clicado usando o parâmetro de comando.

Etapa 1: No comando do seu relé, crie uma propriedade simples que mantenha o valor do objeto do parâmetro. Você pode chamá -lo de parameterValue ou qualquer nome que preferir.

public object ParameterValue
{
  get;
  set;
}

Etapa 2: No método Execute da classe RellayCommand, defina o valor ou a propriedade criada acima como o parâmetro a partir do método Execute.

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

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

Etapa 3: Agora, quando você pode vincular o CommandParameter no XAML a qualquer valor que deseja recuperar quando o comando for executado. exemplo:

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

Se você tem um comando chamado ChickEncommand, quando executado, você pode acessar o parâmetro: chickencommand.parameterValue

Espero que isso ajude alguém. Obrigado por toda a sua ajuda anterior.

Não posso substituir uma referência ao nome do método para a expressão LAMDA por um erro de compilação. Aparentemente, e de modo algum surpreendentemente, uma referência não estática do nome do método não pode ser usada no lugar de um lambda. Eu dificilmente vejo isso como "complexidade adicional". Passar de forma consistente faz sentido para mim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top