В настоящее время я изучаю WPF и MVVM, я думаю, что понимаю большую часть этого и как это работает, но я столкнулся с чем-то при использовании RelayCommand (или DelegateCommand ), чего я не понимаю. Я думаю, это связано с тем, как работают делегаты.
Обратите внимание, что приведенный ниже код на данный момент находится только в тестовых решениях, поэтому нет живого кода. Также я рассматриваю это для команд, которым не требуется такой параметр, как close, и чтобы понять, почему это работает.
Итак, если я возьму RelayCommand, созданный Джошем Смитом(http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030)Я могу настроить такую команду:
RelayCommand updateTextContentCommand;
public ICommand UpdateTextContentCommand
{
get
{
if (updateTextContentCommand == null)
{
updateTextContentCommand = new RelayCommand(
param => this.UpdateTextContentCommand_Execute());
}
return updateTextContentCommand;
}
}
с этим методом выполнения:
public void UpdateTextContentCommand_Execute()
{
this.TextContent = DateTime.Now.ToString();
}
Я использовал простую привязку к TextBlock, чтобы увидеть результат, и команда привязана к кнопке. Это прекрасно работает. Чего я не понимаю, так это использования лямбда-выражения для создания команды. Action
ожидает параметр, не так ли? так почему этот код работает?
Если я изменю код выше на
if (updateTextContentCommand == null)
{
updateTextContentCommand = new RelayCommand(
this.UpdateTextContentCommand_Execute());
}
Я получаю эту ошибку:
*Лучшее совпадение перегруженного метода для 'MVVM.RelayCommandTesting.Framework.RelayCommand.RelayCommand (System.Action )' имеет некоторые недопустимые аргументы
Аргумент 1 :не может преобразовать «void» в «System.Action» *
. и удаление ()
после выполнения дает эту ошибку:
Аргумент 1 :не может преобразовать «группу методов» в «System.Action»
. Но если я изменю код вот так:
if (updateTextContentCommand == null)
{
updateTextContentCommand = new RelayCommand(
this.UpdateTextContentCommand_Execute);
}
public void UpdateTextContentCommand_Execute(object param)
{
this.TextContent = DateTime.Now.ToString();
}
он соответствует и работает нормально. Если я изменю представление для использования CommandParameter, я смогу использовать param для установки текстового содержимого с помощью этого метода, но если я использую лямбда-стиль, мне нужно передать параметр в строку, чтобы он был похож на этот param => this.UpdateTextContentCommand_Execute(param)
.
В моем тесте я жестко кодирую значение CommandParameter, но я предполагаю, что это, скорее всего, будут данные, привязанные к свойству ViewModel в реальной системе, поэтому вы сможете передать параметр в стиле лямбда.
Кто-нибудь может объяснить, почему версия без параметров работает с лямбда-стилем, пожалуйста?
Спасибо, что нашли время, чтобы прочитать это.
Кажется, в приведенном ниже вопросе также были вопросы о лямбде, но я не вижу, чтобы он отвечал на мой вопрос.
Передача параметра с помощью RelayCommand, определенного в ViewModel (из примера Джоша Смита)