Передача параметра с использованием RelayCommand, определенного в ViewModel (из примера Джоша Смита) - PullRequest
23 голосов
/ 01 мая 2009

Я хотел бы передать параметр, определенный в XAML (View) моего приложения, в класс ViewModel с помощью RelayCommand. Я следовал превосходной статье Джоша Смита о MVVM и реализовал следующее.

XAML код

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

Код модели представления

  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

Я установил точку останова в методе CommandWithAParameter и заметил, что для параметра aParameter было установлено значение «Apple», а не «Orange». Это кажется очевидным, так как метод CommandWithAParameter вызывается с литеральной строкой «Apple».

Однако, просматривая стек выполнения, я вижу, что "Orange", CommandParameter, который я установил в XAML, является значением параметра для реализации RelayCommand метода интерфейса ICommand Execute.

То есть значение параметра в методе ниже стека выполнения равно "Orange",

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

Я пытаюсь выяснить, как создать свойство RelayCommand ACommandWithAParameter, чтобы оно могло вызывать метод CommandWithAParameter с помощью CommandParameter «Orange», определенного в XAML.

Есть ли способ сделать это?

Почему я хочу это сделать? Часть "Локализация на лету" В моей конкретной реализации я хочу создать SetLanguage RelayCommand, который можно привязать к нескольким кнопкам. Я хотел бы передать двухсимвольный идентификатор языка («en», «es», «ja» и т. Д.) В качестве CommandParameter, и он должен быть определен для каждой кнопки «set language», определенной в XAML. Я хочу избежать необходимости создавать команду SetLanguageToXXX для каждого языка, поддерживающего и жестко кодирующего двухсимвольный идентификатор языка в каждой RelayCommand в ViewModel.

Ответы [ 6 ]

29 голосов
/ 01 мая 2009

Я не понимаю, почему у вас есть дополнительная сложность определения лямбда-кода Почему бы просто не сделать это:

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

private void CommandWithAParameter(object state)
{
    var str = state as string;
}
13 голосов
/ 01 мая 2009

Вы передадите параметр в лямбде команде следующим образом:

if (_aCommandWithAParameter == null)
{           
    _aCommandWithAParameter = new RelayCommand(               
        param => this.CommandWithAParameter(param)
        );        
}
6 голосов
/ 18 декабря 2013

Ничто не опубликовано здесь, прежде чем работал на меня.

Оказывается, все ответы отсутствуют <object> после RelayCommand!

Это работает для меня:

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

Если вы хотите использовать метод CanExecute, используйте следующий код:

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

private bool OkCommand_CanExecute(object obj) { }
2 голосов
/ 09 июля 2012

Вот простое решение для параметра команды, поскольку я искал помощи по этому вопросу. Я не мог найти в Интернете ничего достаточно простого. Следующее решение хорошо работает, когда вы используете relaycommand. У меня было несколько гиперссылок, для которых мне нужно было получить значение URL, по которому щелкали с помощью параметра команды.

Шаг 1: В вашей команде реле создайте простое свойство, которое будет содержать значение объекта параметра. Вы можете назвать его параметром-значением или любым другим именем, которое вы предпочитаете.

public object ParameterValue
{
  get;
  set;
}

Шаг 2. В методе Execute класса RelayCommand установите значение или свойство, созданное выше, для параметра из метода Execute.

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

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

Шаг 3: Теперь, когда вы можете связать CommandParameter в xaml с любым значением, которое вы хотите получить при выполнении команды. пример:

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

Если у вас есть команда по имени chickenCommand, при ее выполнении вы можете получить доступ к параметру: chickenCommand.ParameterValue

Надеюсь, это кому-нибудь поможет. Спасибо за вашу предыдущую помощь.

2 голосов
/ 22 декабря 2010

Я просто пытаюсь продать свою точку, проверьте, работает ли это ...

http://mywpf -visu.blogspot.com / 2009/12 / релейно-командной как к пасс parameter.html

1 голос
/ 28 марта 2010

Я не могу заменить ссылку на имя метода для выражения lamda в случае ошибки компиляции. Очевидно, что неудивительно, что вместо лямбды-ссылки не может использоваться ссылка на имя нестатического метода. Я вряд ли вижу это как «дополнительную сложность». Последовательное прохождение лямд имеет смысл для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...