使用ViewModel中定义的RelayCommand传递参数(来自Josh Smith示例)
-
03-07-2019 - |
题
我想通过使用RelayCommand将我的应用程序的XAML(View)中定义的参数传递给ViewModel类。我跟着 Josh Smith关于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设置为<!> quot; Apple <!>“;而不是<!> << Orange <!>。这看起来很明显,因为使用文字String <!>“Apple <!>”调用方法CommandWithAParameter。
但是,查看执行堆栈,我可以看到<!>“Orange <!>”,我在XAML中设置的CommandParameter是RelayCommand实现ICommand Execute接口方法的参数值。
这是执行堆栈下面方法中参数的值是<!>;橙色<!>;,
public void Execute(object parameter)
{
_execute(parameter);
}
我想弄清楚的是如何创建RelayCommand ACommandWithAParameter属性,以便它可以使用CommandParameter <!>“Orange <!>”调用CommandWithAParameter方法。在XAML中定义。
有办法做到这一点吗?
为什么我要这样做?部分<!>“On The Fly Localization <!>”; 在我的特定实现中,我想创建一个可以绑定到多个按钮的SetLanguage RelayCommand。我想传递两个字符语言标识符(<!> quot; en <!> quot;,<!> quot; es <!> quot;,<!> quot; ja <!> quot;等)as CommandParameter并为每个<!>“set语言<!>”定义; XAML中定义的按钮。我想避免为每种语言创建一个SetLanguageToXXX命令,支持并将两个字符语言标识符硬编码到ViewModel中的每个RelayCommand中。
解决方案
我不明白为什么你有一个额外的复杂性,首先指定lambda。为什么不这样做:
if (_aCommandWithAParameter == null)
{
_aCommandWithAParameter = new RelayCommand<object>(CommandWithAParameter);
}
private void CommandWithAParameter(object state)
{
var str = state as string;
}
其他提示
你会将lambda中的param传递给命令,如下所示:
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
这是命令参数的简单解决方案,因为我正在寻找有关该主题的帮助。我在网上找不到任何简单的东西。使用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
我希望这有助于某人。感谢您以前的所有帮助。
我无法使用编译错误替换lamda表达式的方法名称的引用。显然,并不奇怪,不能使用非静态方法名称引用来代替lambda。我几乎没有看到它作为<!>添加复杂性<!>“;一直传递lamdas对我来说很有意义。