【问题标题】:How do I invoke RelayCommand with multiple parameters?如何使用多个参数调用 RelayCommand?
【发布时间】:2018-04-08 12:35:11
【问题描述】:

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

new RelayCommand<MyClass>()

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

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

对吗?

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

【问题讨论】:

    标签: c# wpf xaml mvvm-light


    【解决方案1】:

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

    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"/>
    

    我不想在您的视图中定义类。对于关注点分离,视图应该只知道要绑定的属性而不是模型。

    【讨论】:

      【解决方案2】:

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

      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>
      

      【讨论】:

        【解决方案3】:

        还有另一种方法可以使用IMultiValueConverter

        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();
            }
        }  
        

        然后在 xaml(按钮代码)中:

        <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>  
        

        这是包含转换器的代码:

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

        然后在你的窗口资源标签中:

        <converter:MultiValueConverter x:Key="MultiValueConverter"/>  
        



        这样你可以在传递参数时使用 Binding 而无需实现DependencyProperties

        【讨论】:

          【解决方案4】:

          我是这样做的:

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

            private RelayCommand<object> _YourCommand;
            
            public RelayCommand<object> YourCommand
            {
                get
                {
                    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 中(当然,绑定中的路径必须是对绑定对象的有效引用)

          <Button Command="{Binding YourCommand}">
              	<Button.CommandParameter>
              	    <MultiBinding>
              	        <Binding Path="Item1"/>
              	        <Binding Path="Item2"/>
              	        <Binding Path="Item3"/>
              	    </MultiBinding>
              	</Button.CommandParameter>
          </Button>

          【讨论】:

            猜你喜欢
            • 2023-04-03
            • 2012-01-06
            • 2014-03-30
            • 1970-01-01
            • 2018-12-25
            • 1970-01-01
            • 2012-06-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多