如何使用多个参数调用RelayCommand?

时间:2017-10-27 01:02:34

标签: c# wpf xaml mvvm-light

我需要更改我们编写的WPF应用程序中的某些功能。我们使用MVVM Light来实现MVVM。每当我们需要将一些参数传递给方法时,我们就使用了MVVM Light的Messenger类。我必须将3个参数传递给一个方法,但我想我会尝试不使用Messenger类,但我希望我可以使用RelayCommand()方法。我做了一次搜索,并在几年前在SO上找到this post。但至少对我而言,我认为这不会起作用,因为它只使用一种类型;这种情况下的字符串。在做了一些试验并意识到我做错了之后,我决定我可以创建一个具有我需要的3个值的类作为类的属性,将其放入Models文件夹并使用

new RelayCommand<MyClass>()

所以,第一个问题,只是为了验证我是否有正确的想法,我想我会做这样的事情:

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)

这是对的吗?

假设上面的答案是肯定的,那么当我在XAML中绑定它时,如何将参数传递给它?此命令将与窗口/页面上的按钮相关联,因此我将使用Button的Command属性。如何实际传入MyClass实例Prop_A,Prop_B和Prop_C的值?

4 个答案:

答案 0 :(得分:2)

  

所以,第一个问题,只是为了验证我是否有正确的想法,我   我想我会做这样的事情:

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)

这是正确的。

  

假设上面的答案是肯定的,那么我该如何实际通过   我在XAML中绑定它时的参数?这个命令是   将与窗口/页面上的按钮相关联,所以我会   使用Button的Command属性。我如何实际传入   MyClass实例Prop_A,Prop_B和Prop_C的值?

这实际上取决于Prop_A,Prop_B和Prop_C来自何处。如果这些属性已经在视图模型中,那么您无需使用XAML传递参数。

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)

将更改为

new RelayCommand<object>((param) => 
{
    // param is not used.
    var mc = this.MC; // assuming your view model holds the mc value
    MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C);
});

我们必须确保在加载视图模型时,我们拥有所需的一切。否则,使用IoC来获取您需要的任何内容。

将参数绑定到命令通常对于计算机应用程序非常有用,您可以将按钮值传递给命令,例如0 - 9.

<Button Grid.Row="0" Grid.Column="1" Content="7" Command="{Binding PerformAction}" CommandParameter="7"/>

我希望远离您在视图中定义类。为了分离关注点,视图应该只知道要绑定的属性而不是模型。

答案 1 :(得分:1)

  

所以,第一个问题,只是为了验证我是否有正确的想法,我想我会做这样的事情:

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)
     

这是对的吗?

是的,是的。

  

如何实际传入MyClass实例Prop_A,Prop_B和Prop_C的值?

只需创建一个类的实例,该类将xaml中的参数保存为命令参数:

<Button Command="{Binding Command}">
    <Button.CommandParameter>
        <local:MyClass Prop_A="a value" Prop_B="b value" Prop_C="c value" />
    </Button.CommandParameter>
</Button>

答案 2 :(得分:1)

使用var termarray = ["help", "help me", "-h", "--help"]; commandterm = $("#search-bar").val(); var displayType ; var indexOfArray = jQuery.inArray(commandterm, termarray); if (indexOfArray == -1) { displayType = "none" } else { displayType = "block"; } $("#helpblock").css("display",displayType);

还有另一种方法可以做到这一点
IMultiValueConverter

然后在xaml(按钮代码):

class MultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var item in values)
        {
            //process the properties passed in and you will need to unbox those parameters
        }
        return new object();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}  

以下是包含转换器的代码:

<Button Content="Test" Style="{StaticResource contextMenuAware}" Command="{Binding MultiParameterCommand}">
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource MultiValueConverter}">
            <Binding Path="Items"/>
            <!-- Pass more Bindings here or static values -->
        </MultiBinding>
    </Button.CommandParameter>
</Button>  

然后在你的Window Resources标签:

xmlns:converter="clr-namespace:SO_app.Converters"  


这样,您可以在传递参数时使用Binding,而无需实现<converter:MultiValueConverter x:Key="MultiValueConverter"/>

答案 3 :(得分:1)

我是这样做的:

  1. 您的CommandRelay对象将对象作为参数,您将该对象转换为object [],然后将每个元素转换为其自己的对象。

    私人RelayCommand _YourCommand; public RelayCommand YourCommand {     得到     {

        return _YourCommand
            ?? (_YourCommand = new RelayCommand<object>(
                                  p =>
                                  {
                                      var values = (object[]) p;
                                      int item1 = int.Parse(values[0].ToString());
                                      string item2 = values[1].ToString();
                                      double item3 = double.Parse(values[2].ToString());
    
                                  }));
    }
    

    }

  2. 然后,在xaml中(当然,你的绑定路径必须是对绑定对象的有效引用)

  3. &#13;
    &#13;
    <Button Command="{Binding YourCommand}">
        	<Button.CommandParameter>
        	    <MultiBinding>
        	        <Binding Path="Item1"/>
        	        <Binding Path="Item2"/>
        	        <Binding Path="Item3"/>
        	    </MultiBinding>
        	</Button.CommandParameter>
    </Button>
    &#13;
    &#13;
    &#13;