我想通过使用RelayCommand将我的应用程序的XAML(View)中定义的参数传递给ViewModel类。我跟着Josh Smith's excellent article on 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方法中设置了一个断点,并观察到aParameter设置为“Apple”,而不是“Orange”。这看起来很明显,因为使用文字字符串“Apple”调用CommandWithAParameter方法。
但是,查看执行堆栈,我可以看到“Orange”,我在XAML中设置的CommandParameter是RelayCommand实现ICommand Execute接口方法的参数值。
这是执行堆栈下面方法中参数的值是“Orange”,
public void Execute(object parameter)
{
_execute(parameter);
}
我想弄清楚的是如何创建RelayCommand ACommandWithAParameter属性,以便它可以使用XAML中定义的CommandParameter“Orange”调用CommandWithAParameter方法。
有办法做到这一点吗?
为什么我要这样做? “On The Fly Localization”的一部分 在我的特定实现中,我想创建一个可以绑定到多个按钮的SetLanguage RelayCommand。我想将两个字符语言标识符(“en”,“es”,“ja”等)作为CommandParameter传递,并为XAML中定义的每个“set language”按钮定义。我想避免为每种语言创建一个SetLanguageToXXX命令,支持并将两个字符语言标识符硬编码到ViewModel中的每个RelayCommand中。
答案 0 :(得分:28)
我不明白为什么你有一个额外的复杂性,首先指定lambda。为什么不这样做:
if (_aCommandWithAParameter == null)
{
_aCommandWithAParameter = new RelayCommand<object>(CommandWithAParameter);
}
private void CommandWithAParameter(object state)
{
var str = state as string;
}
答案 1 :(得分:13)
你会将lambda中的param传递给命令,如下所示:
if (_aCommandWithAParameter == null)
{
_aCommandWithAParameter = new RelayCommand(
param => this.CommandWithAParameter(param)
);
}
答案 2 :(得分:6)
之前没有任何内容发布在我身上。
事实证明,<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) { }
答案 3 :(得分:2)
我只是想卖掉我的观点,看看这是否有效......
http://mywpf-visu.blogspot.com/2009/12/relay-command-how-to-pass-parameter.html
答案 4 :(得分:2)
这是命令参数的简单解决方案,因为我正在寻找有关该主题的帮助。我在网上找不到任何简单的东西。使用relay命令时,以下解决方案很有效。 我有一些超链接,我需要获取使用命令参数单击的url值。
步骤1:在relay命令中,创建一个包含参数对象值的简单属性。您可以将其称为参数值或您喜欢的任何名称。
public object ParameterValue
{
get;
set;
}
步骤2:在RelayCommand类的Execute方法中,将上面创建的值或属性设置为Execute方法中的参数。
readonly Action<object> m_execute; // Action to execute
public void Execute(object parameter)
{
this.ParameterValue = parameter;
m_execute(parameter);
}
步骤3:现在,当您可以将xaml中的CommandParameter绑定到要执行命令时要检索的任何值。 例如:
<TextBlock>
<Hyperlink Command="{Binding Path=NavigateUrlCmd}"
CommandParameter="{Binding ElementName=tbwebsite, Path=Text}">
<TextBlock Name="tbwebsite" Text="{Binding Path=website}"/>
</Hyperlink>
</TextBlock>
如果你有一个名为chickenCommand的命令,那么在执行时你可以访问参数: chickenCommand.ParameterValue
我希望这有助于某人。感谢您以前的所有帮助。
答案 5 :(得分:1)
我无法使用编译错误替换lamda表达式的方法名称的引用。显然,并不奇怪,不能使用非静态方法名称引用来代替lambda。我几乎不认为它“增加了复杂性”。一直传递lamdas对我来说很有意义。