如何使用 MVVM 在 WPF 应用程序中的 InvokeCommandAction 中将多个参数作为 CommandParameter 传递

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12601684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 05:33:15  来源:igfitidea点击:

How to pass Multiple parameters as CommandParameter in InvokeCommandAction In WPF App Using MVVM

c#wpfmvvm

提问by SST

I am using System.Windows.interactivity.dll to get mouse events in my ViewModel in the following manner.

我正在使用 System.Windows.interactivity.dll 以下列方式在我的 ViewModel 中获取鼠标事件。

 <ListBox x:Name="listBox" ItemsSource="{Binding HeaderList}" DisplayMemberPath="Text" Width="Auto"   Margin="0,0,0,300" Height="Auto"  >
    <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseLeftButtonUp">
                <i:InvokeCommandAction Command="{Binding MouseLeftButtonUpCommand}" 
                         CommandParameter="{Binding SelectedItem, ElementName=listBox}"/>
        </i:EventTrigger>

        </i:Interaction.Triggers>
</ListBox>

and in ViewModel.

并在 ViewModel 中。

        public class Headers
    {
        public Headers()
        {
            IsSelected = false;
        }

        public string Text { get; set; }
        public ListBox Control { get; set; }
        public bool IsSelected { get; set; }
    }
   public ObservableCollection<Headers> HeaderList
    {
        get { return _headerList; }
        set
        {
            _headerList = value;
            base.OnPropertyChanged("HeaderList");
        }

    }
 public ICommand MouseLeftButtonUpCommand { get; set; }
 public DesignTemplateViewModel()
    {
        string file = SessionHelper.FilePath;
        List<string> columns = new List<string>();


        if (!string.IsNullOrEmpty(file))
        {
            ExcelHelper Excel = new ExcelHelper(file);
            columns = Excel.GetHeader();
        }
        else
        {
            columns.Add("Name");
            columns.Add("FatherName");
            columns.Add("MotherName");
            columns.Add("Class");
            columns.Add("RollNo");
            columns.Add("ModeOfTransport");
            columns.Add("Phone");
            columns.Add("Mobile");
        }
        HeaderList = new ObservableCollection<Headers>();

        foreach (string column in columns)
        {
            HeaderList.Add(new Headers
            {
                Text = column,
            });
        }

        MouseLeftButtonUpCommand = new RelayCommand((item) => OnMouseLeftButtonUp((Headers)item));
    }
  private void OnMouseLeftButtonUp(Headers sender)
    {
        ListBox control = sender.Control as ListBox;
        DragDrop.DoDragDrop(control, sender.Text, DragDropEffects.Copy);
    }

So here I need to pass multiple objects such as Control that generated this event, Mouse related properties etc. Now I am Passing single parameter and this code is working fine. So My Questions is that how can pass Multiple parameters from Xaml(View) and access them on this ViewModel. Any code help??

所以在这里我需要传递多个对象,例如生成此事件的控件、鼠标相关属性等。现在我正在传递单个参数并且此代码工作正常。所以我的问题是如何从 Xaml(View) 传递多个参数并在这个 ViewModel 上访问它们。任何代码帮助?

回答by Aghilas Yakoub

You can try with custom Converter and MultiBinding

您可以尝试自定义 Converter and MultiBinding

<CommandParameter>
      <MultiBinding Converter="{StaticResource CustomConverter}">
       <Binding ElementName=".." Path=".."/>
       <Binding ElementName=".." Path=".."/>
      </MultiBinding>
</CommandParameter>

Converter

转换器

class CustomConverter : IMultiValueConverter 
{
    public object Convert (object[] Values, Type Target_Type, object Parameter, CultureInfo culture) 
    {
        var findCommandParameters = new FindCommandParameters();
        findCommandParameters.Property1 = (string)values[0];
        findCommandParameters.Property1 = (string)values[1];
        return findCommandParameters;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter,   System.Globalization.CultureInfo culture)
    {
       throw new NotImplementedException();
    }
}

Parameters

参数

public class FindCommandParameters
{
  public string Property1 { get; set; }
  public string Property2 { get; set; }
}

回答by TomerBu

I Agree with Aghilas. That's how it's done. I improved upon Aghilas's code to clarify what was missing. note that "i:InvokeCommandAction.CommandParameter" must be put inside the invokeCommandAction declaration.

我同意阿吉拉斯的观点。就是这样完成的。我改进了 Aghilas 的代码以澄清缺少的内容。请注意,“i:InvokeCommandAction.CommandParameter”必须放在 invokeCommandAction 声明中。

    <ListBox x:Name="listBox" ItemsSource="{Binding HeaderList}" DisplayMemberPath="Text" Width="Auto"   Margin="0,0,0,300" Height="Auto"  >
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseLeftButtonUp">
                <i:InvokeCommandAction Command="{Binding MouseLeftButtonUpCommand}">
                    <i:InvokeCommandAction.CommandParameter>
                        <MultiBinding Converter="{StaticResource XAMLResourceAddConverter}">
                            <Binding ElementName="listBox" Path="SelectedItem"/>
                            <Binding ElementName="listBox" Path="SelectedItem"/>
                        </MultiBinding>
                    </i:InvokeCommandAction.CommandParameter>
                </i:InvokeCommandAction>
            </i:EventTrigger>

        </i:Interaction.Triggers>
    </ListBox>