使用ViewModel中定义的RelayCommand传递参数(来自Josh Smith示例)

ees*_*esh 24 .net data-binding wpf lambda mvvm

我想通过使用RelayCommand将我的应用程序的XAML(View)中定义的参数传递给ViewModel类.我关注了Josh Smith关于MVVM的优秀文章,并实现了以下内容.

XAML代码

        <Button 
        Command="{Binding Path=ACommandWithAParameter}"
        CommandParameter="Orange"
        HorizontalAlignment="Left" 
        Style="{DynamicResource SimpleButton}" 
        VerticalAlignment="Top" 
        Content="Button"/>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我在CommandWithAParameter方法中设置了一个断点,并观察到aParameter设置为"Apple",而不是"Orange".这看起来很明显,因为使用文字字符串"Apple"调用CommandWithAParameter方法.

但是,查看执行堆栈,我可以看到"Orange",我在XAML中设置的CommandParameter是RelayCommand实现ICommand Execute接口方法的参数值.

也就是执行堆栈下面方法中参数的值是"Orange",

  public void Execute(object parameter)
  {
     _execute(parameter);
  }
Run Code Online (Sandbox Code Playgroud)

我想弄清楚的是如何创建RelayCommand ACommandWithAParameter属性,以便它可以使用XAML中定义的CommandParameter"Orange"调用CommandWithAParameter方法.

有没有办法做到这一点?

我为什么要这样做?"On The Fly Localization"的一部分在我的特定实现中,我想创建一个可以绑定到多个按钮的SetLanguage RelayCommand.我想将两个字符语言标识符("en","es","ja"等)作为CommandParameter传递,并为XAML中定义的每个"set language"按钮定义.我想避免为每种语言创建一个SetLanguageToXXX命令,支持并将两个字符语言标识符硬编码到ViewModel中的每个RelayCommand中.

Ken*_*art 30

我不明白为什么你有一个额外的复杂性,首先指定lambda.为什么不这样做:

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

private void CommandWithAParameter(object state)
{
    var str = state as string;
}
Run Code Online (Sandbox Code Playgroud)

  • `RelayCommand` 构造函数接受 `Action&lt;object&gt;`,因此传递给它的方法必须与该委托匹配。我上面的代码示例中的那个是,因为它需要一个对象参数。如果您的方法不接受对象参数,则最简单的转换方法确实是使用 lambda:`new RelayCommand(_ =&gt; MyMethod())`(下划线是未使用的 lambda 参数的常规名称) (2认同)

Pau*_*der 13

您将lambda中的参数传递给命令,如下所示:

if (_aCommandWithAParameter == null)
{           
    _aCommandWithAParameter = new RelayCommand(               
        param => this.CommandWithAParameter(param)
        );        
}
Run Code Online (Sandbox Code Playgroud)


JCH*_*H2k 7

之前没有发布任何内容为我工作过.

事实证明,所有的答案都丢失<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;
}
Run Code Online (Sandbox Code Playgroud)

如果要使用CanExecute方法,请使用以下代码:

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

private bool OkCommand_CanExecute(object obj) { }
Run Code Online (Sandbox Code Playgroud)


小智 5

这是命令参数的一个简单解决方案,因为我正在寻找有关该主题的帮助。我在网上找不到任何足够简单的东西。当您使用中继命令时,以下解决方案效果很好。我有一些超链接,我需要获取使用命令参数单击的 url 值。

步骤 1:在您的中继命令中,创建一个简单的属性来保存参数对象值。您可以将其命名为“参数值”或任何您喜欢的名称。

public object ParameterValue
{
  get;
  set;
}
Run Code Online (Sandbox Code Playgroud)

步骤 2:在 RelayCommand 类的 Execute 方法中,将上面创建的值或属性设置为 Execute 方法中的参数。

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

public void Execute(object parameter)
 {
   this.ParameterValue = parameter;
   m_execute(parameter);
 }
Run Code Online (Sandbox Code Playgroud)

步骤 3:现在,您可以将 xaml 中的 CommandParameter 绑定到执行命令时想要检索的任何值。例子:

<TextBlock>
  <Hyperlink Command="{Binding Path=NavigateUrlCmd}"
             CommandParameter="{Binding ElementName=tbwebsite, Path=Text}">
    <TextBlock Name="tbwebsite" Text="{Binding Path=website}"/>
  </Hyperlink>
</TextBlock> 
Run Code Online (Sandbox Code Playgroud)

如果您有一个名为 ChickenCommand 的命令,则在执行时您可以访问参数:chickenCommand.ParameterValue

我希望这对某人有帮助。感谢您之前的所有帮助。