我有一个命令,我使用以下标准语法从我的XAML文件执行:
<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/>
这很好用,直到我意识到我需要从视图中获取两条信息,以便按照用户期望的方式完成此操作(画布的宽度和高度)。
似乎可以将数组作为参数传递给我的命令,但是我没有看到在CommandParameter中指定绑定到我的两个canvas属性的方法:
<Button Content="Zoom"
Command="{Binding MyViewModel.ZoomCommand"
CommandParameter="{Binding ElementName=MyCanvas, Path=Width}"/>
如何将宽度和高度传递给我的命令?使用XAML中的命令似乎不太可能,我需要在代码隐藏中连接一个单击处理程序,以便将此信息传递给我的缩放方法。
首先,如果您正在使用MVVM,通常会通过绑定到视图的单独属性向VM提供此信息。这样可以节省您必须将任何参数传递给您的命令。
但是,您也可以使用多重绑定并使用转换器来创建参数:
<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>
在您的转换器中:
public class YourConverter : IMultiValueConverter
{
public object Convert(object[] values, ...)
{
return values.Clone();
}
...
}
然后,在您的命令执行逻辑中:
public void OnExecute(object parameter)
{
var values = (object[])parameter;
var width = (double)values[0];
var height = (double)values[1];
}
在所选解决方案的转换器中,您应该添加values.Clone(),否则命令中的参数将结束null
public class YourConverter : IMultiValueConverter
{
public object Convert(object[] values, ...)
{
return values.Clone();
}
...
}
在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;
}
如果您的值是静态的,则可以使用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>
关于在转换器中使用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;
}
}
然后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;
}
并使用转换器多绑定来创建参数(带有两个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>