Передача параметра с помощью RelayCommand, определенной в ViewModel (из примера Джоша Смита)
-
03-07-2019 - |
Вопрос
Я хотел бы передать параметр, определенный в XAML (View) моего приложения, классу ViewModel с помощью RelayCommand.Я последовал за ним Превосходная статья Джоша Смита о MVVM и реализовали следующее.
Код XAML
<Button
Command="{Binding Path=ACommandWithAParameter}"
CommandParameter="Orange"
HorizontalAlignment="Left"
Style="{DynamicResource SimpleButton}"
VerticalAlignment="Top"
Content="Button"/>
Код 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
Я установил точку останова в методе CommandWithAParameter и заметил, что параметру было присвоено значение "Яблоко", а не "Апельсин".Это кажется очевидным, поскольку метод CommandWithAParameter вызывается с буквальной строкой "Apple".
Однако, просматривая стек выполнения, я вижу, что "Orange", параметр CommandParameter, который я установил в XAML, является значением параметра для реализации RelayCommand метода интерфейса выполнения ICommand.
То есть значение параметра в приведенном ниже методе стека выполнения равно "Оранжевому".,
public void Execute(object parameter)
{
_execute(parameter);
}
Что я пытаюсь выяснить, так это как создать свойство RelayCommand ACommandWithAParameter таким образом, чтобы оно могло вызывать метод CommandWithAParameter с CommandParameter "Orange", определенным в XAML.
Есть ли способ сделать это?
Почему я хочу это сделать?Часть "Локализации на лету" В моей конкретной реализации я хочу создать setLanguage RelayCommand, который может быть привязан к нескольким кнопкам.Я хотел бы передать двухсимвольный идентификатор языка ("en", "es", "ja" и т.д.) В качестве CommandParameter и определить его для каждой кнопки "установить язык", определенной в XAML.Я хочу избежать необходимости создавать команду SetLanguageToXXX для каждого языка, поддерживающего и жестко кодирующего двухсимвольный языковой идентификатор в каждой RelayCommand в ViewModel.
Решение
Я не понимаю, почему у вас возникает дополнительная сложность с указанием лямбда-выражения в первую очередь.Почему бы просто не сделать это:
if (_aCommandWithAParameter == null)
{
_aCommandWithAParameter = new RelayCommand<object>(CommandWithAParameter);
}
private void CommandWithAParameter(object state)
{
var str = state as string;
}
Другие советы
Вы передадите параметр в лямбде команде следующим образом:
if (_aCommandWithAParameter == null)
{
_aCommandWithAParameter = new RelayCommand(
param => this.CommandWithAParameter(param)
);
}
Ничто из опубликованного здесь раньше у меня не работало.
Оказывается, во всех ответах отсутствует <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) { }
Я просто пытаюсь донести свою точку зрения, проверьте, работает ли это...
http://mywpf-visu.blogspot.com/2009/12/relay-command-how-to-pass-parameter.html
Вот простое решение для commandparameter, поскольку я искал помощь по этому вопросу.Я не смог найти в Интернете ничего достаточно простого.Следующее решение хорошо работает, когда вы используете relaycommand.У меня было несколько гиперссылок, для которых мне нужно было получить значение URL, по которому был сделан щелчок с помощью параметра command.
Шаг 1:В вашей команде relay создайте простое свойство, которое будет содержать значение объекта parameter.Вы могли бы назвать это параметрическим значением или любым другим именем, которое вы предпочитаете.
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.Значение параметра
Я надеюсь, что это кому-нибудь поможет.Спасибо вам за всю вашу предыдущую помощь.
Я не могу заменить ссылку на имя метода для выражения lamda с ошибкой компиляции.Очевидно, и это ни в коем случае не удивительно, что нестатическая ссылка на имя метода не может использоваться вместо лямбда-выражения.Я вряд ли рассматриваю это как "дополнительную сложность".Постоянное прохождение ламдаса имеет для меня смысл.