mvvm模式里command经常写在vm中。而command只能传入一个对象作为执行时的参数,若要传入多个参数,在.cs文件(即调用vm的command)中,只需要把多个参数加到一个集合里,传入command时就把集合当单参数对象传入就行了。
public ICommand CMD
{
get
{
return new DelegateCommand<object[]>(x =>
{
var obj0=x[0].ToString();
var obj1=Convert.ToInt32(x[1]);
//.................
});
}
}
//调用处:
{
.........
v.CMD.Execute(new object[]{"1111",456});//v为该CMD所在的vm的实例
}
但如果在xaml中用到如blend的InvokeCommandAction进行command的绑定,又如何在xaml中进行传入多参数??
方法有许多种。小弟不才,自己开发了2个类来解决这问题。先说明一下,此方法只使用与silverlight4或以上版本。
先看看应用:
<Button Command="{Binding CMD}">
<Button.CommandParameter>
<sw:MultiDelegateObjects>
<sw:DelegateObject Key="s1" Value="{Binding Tag, ElementName=t1}"/>
<sw:DelegateObject Key="s2" Value="888"/>
</sw:MultiDelegateObjects>
</Button.CommandParameter>
</Button>
vm:
public ICommand CMD
{
get
{
return new DelegateCommand<MultiDelegateObjects>(x =>
{
//使用key或索引来获取集合的元素。key不区分大小写.
//使用key可以不要考虑在xaml中的位置。
var obj0=x["s1"] as Page;//或x.GetValue<Page>("s1");
var obj1=x["s2"].ToString();
var obj2=x[1].ToString();//obj1==obj2;
//.................
});
}
}
using System;using System.Windows.Input;namespace System.Windows.Input
{
public class DelegateCommand<T> : ICommand
{
public DelegateCommand() : this(null, null)
{ }
public DelegateCommand(Action<T> executeMethod) : this(executeMethod, null)
{ }
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
TargetExecuteMethod = executeMethod;
TargetCanExecuteMethod = canExecuteMethod;
}
public Action<T> TargetExecuteMethod
{ get; set; }
public Func<T, bool> TargetCanExecuteMethod
{ get; set; }
public void OnCanExecuteChanged()
{
this.CanExecuteChanged(this, EventArgs.Empty);
}
public void Execute(T parameter)
{
if (TargetExecuteMethod != null)
TargetExecuteMethod(parameter);
}
public bool CanExecute(T parameter)
{
if (TargetCanExecuteMethod != null)
return TargetCanExecuteMethod(parameter);
if (TargetExecuteMethod != null)
return true;
return false;
}
#region ICommand
bool ICommand.CanExecute(object parameter)
{
return this.CanExecute((T)parameter);
}
void ICommand.Execute(object parameter)
{
this.Execute((T)parameter);
}
public event EventHandler CanExecuteChanged;
#endregion
}
}