使用 WPF 绑定传递两个命令参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1350598/
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
Passing two command parameters using a WPF binding
提问by JasonD
I have a command which I am executing from my XAML file using the following standard syntax:
我有一个使用以下标准语法从 XAML 文件执行的命令:
<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/>
This worked fine until I realized that I needed TWO pieces of information from the view in order to make this operation complete the way users expect (the width and height of the canvas specfically).
这工作得很好,直到我意识到我需要视图中的两条信息才能使此操作按照用户期望的方式完成(特别是画布的宽度和高度)。
It seems like it's possible to pass an array as an argument to my command, but I don't see there being a way to specify the binding to my two canvas properties in the CommandParameter:
似乎可以将数组作为参数传递给我的命令,但我没有看到有一种方法可以在 CommandParameter 中指定与我的两个画布属性的绑定:
<Button Content="Zoom"
Command="{Binding MyViewModel.ZoomCommand"
CommandParameter="{Binding ElementName=MyCanvas, Path=Width}"/>
How do I pass both Width and Height to my command? It doesn't seem like this is possible using commands from XAML and I need to wire up a click handler in my codebehind to get this information to pass to my zoom method.
如何将宽度和高度都传递给我的命令?使用来自 XAML 的命令似乎不可能做到这一点,我需要在我的代码隐藏中连接一个单击处理程序,以便将此信息传递给我的缩放方法。
回答by Kent Boogaart
Firstly, if you're doing MVVM you would typically have this information available to your VM via separate properties bound from the view. That saves you having to pass any parameters at all to your commands.
首先,如果您正在执行 MVVM,您通常会通过与视图绑定的单独属性将这些信息提供给您的 VM。这使您不必将任何参数传递给您的命令。
However, you could also multi-bind and use a converter to create the parameters:
但是,您也可以多重绑定并使用转换器来创建参数:
<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource YourConverter}">
<Binding Path="Width" ElementName="MyCanvas"/>
<Binding Path="Height" ElementName="MyCanvas"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
In your converter:
在您的转换器中:
public class YourConverter : IMultiValueConverter
{
public object Convert(object[] values, ...)
{
return values.Clone();
}
...
}
Then, in your command execution logic:
然后,在您的命令执行逻辑中:
public void OnExecute(object parameter)
{
var values = (object[])parameter;
var width = (double)values[0];
var height = (double)values[1];
}
回答by Daniel
In the converter of the chosen solution, you should add values.Clone() otherwise the parameters in the command end null
在所选解决方案的转换器中,您应该添加 values.Clone() 否则命令中的参数为 null
public class YourConverter : IMultiValueConverter
{
public object Convert(object[] values, ...)
{
return values.Clone();
}
...
}
回答by Melinda
Use Tuple in Converter, and in OnExecute, cast the parameter object back to Tuple.
在 Converter 中使用 Tuple,在 OnExecute 中,将参数对象转换回 Tuple。
public class YourConverter : IMultiValueConverter
{
public object Convert(object[] values, ...)
{
Tuple<string, string> tuple = new Tuple<string, string>(
(string)values[0], (string)values[1]);
return (object)tuple;
}
}
// ...
public void OnExecute(object parameter)
{
var param = (Tuple<string, string>) parameter;
}
回答by Maxence
If your values are static, you can use x:Array
:
如果您的值是静态的,您可以使用x:Array
:
<Button Command="{Binding MyCommand}">10
<Button.CommandParameter>
<x:Array Type="system:Object">
<system:String>Y</system:String>
<system:Double>10</system:Double>
</x:Array>
</Button.CommandParameter>
</Button>
回答by alex
About using Tuple in Converter, it would be better to use 'object' instead of 'string', so that it works for all types of objects without limitation of 'string' object.
关于在 Converter 中使用 Tuple,最好使用 'object' 而不是 'string',以便它适用于所有类型的对象,而不受 'string' 对象的限制。
public class YourConverter : IMultiValueConverter
{
public object Convert(object[] values, ...)
{
Tuple<object, object> tuple = new Tuple<object, object>(values[0], values[1]);
return tuple;
}
}
Then execution logic in Command could be like this
那么Command中的执行逻辑可能是这样的
public void OnExecute(object parameter)
{
var param = (Tuple<object, object>) parameter;
// e.g. for two TextBox object
var txtZip = (System.Windows.Controls.TextBox)param.Item1;
var txtCity = (System.Windows.Controls.TextBox)param.Item2;
}
and multi-bind with converter to create the parameters (with two TextBox objects)
并与转换器多重绑定以创建参数(使用两个 TextBox 对象)
<Button Content="Zip/City paste" Command="{Binding PasteClick}" >
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource YourConvert}">
<Binding ElementName="txtZip"/>
<Binding ElementName="txtCity"/>
</MultiBinding>
</Button.CommandParameter>
</Button>