在VM中我们一些方法需要提供给view 使用。其中最简单的方法是直接暴露一个public 的方法由view(在xmal.cs) 中直接调用。如果我们想把这个方法绑定到页面(xaml) 中的事件则需要使用Command. 当然在xmal.cs 中也可以直接使用Command。
View 想使用Command 那么首先必须在VM 实现一个公开的Command属性。
在Windows Phone 的SDK 中 Command的实现必须继承与System.Windows.Input.ICommand接口: 在ICommand 中包含CanExecute 和Execute 方法和一个CanExecuteChanged 事件。
如果Command 是被绑定到页面上的事件中。那么系统在执行Command的时候将先执行 CanExecute 方法
如果方法返回true则执行Execute方法的方式来执行Command。在调用这两个方法的时候Command的参数均会被传入这两个方法。
同时我们建议是自己调用Command使用的话也建议遵循这样的方式。
在使用Command使用必然会增加代码量,当然也带来好处:
1、
可以直接绑定
2、
可以控制状态
代码如下 | 复制代码 |
using System; namespace WeiFan.Utility.Command public DelegateCommand(Action private bool m_isCanExecute = true; } private void FireCanExecuteChanged() #region ICommand Members public event EventHandler CanExecuteChanged; public bool CanExecute(object parameter) args = parameter as T;
public void Execute(object parameter) args = parameter as T; m_excuteAction(args);
|
现在我们先来Command如何实现。一般来说我在代码中实现一个基础的通用Command,已代理的方式在Command 构建的时候传入Execute 方法和CanExecute的具体逻辑。
代码如下:
其中泛型T为Command 参数类型。
那么 我们在VM 中使用该Command 如下:
代码如下 | 复制代码 |
private DelegateCommand public ICommand ClickImageCommand { get { return m_clickImageCommand; } } |
注意这个Command 是调用的时候接受一个 string 类型的参数。 这个Command的CanExecute 永远返回True 也就是说无论什么时候 该Command 都可以执行。
接下来我们来聊聊Command 的参数
首先Command在使用的是有允许传入一个 Object 类型的参数。 如果我们的Command 只接收一个参数到好说 在泛型里面限定类型就OK 了。。。 如果要接受多个参数的话就很蛋疼了。。
在这里我选择采用 一个集合类型将多个参数打包成一个集合传入Command。
考虑到为了让其使用起来友好 又能方便绑定我选择该集合采用简直对的方式 集合中的每个元素包含一个key 和一个value . 元素可以使用index 来索引 可以使用key 来索引。
代码如下:
CommandArg:
代码如下 | 复制代码 |
[ContentProperty("Value")] public CommandArg(string key, Object value) public CommandArg() { } private const string KEY_CAN_NOT_NULL = "绑定参数的key不能为空"; #region DependencyProperty
private static void KeyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) bool m_isSetKey = false; } #endregion public override string ToString()
#region IEquatable接口实现 public bool Equals(CommandArg other) #endregion |
这是集合中单个元素对象
CommandArgs:
代码如下 | 复制代码 |
using System; namespace WeiFan.Utility.Command
void CommandArgs_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) if (containArg != null && !containArg.Equals(arg))
public new void SetValue(DependencyProperty dp, object value) public bool Contains(string key) public new void Add(CommandArg item) /// |
这是参数集合
好了。 接下来的事情我们就来看下 VM 中的Command 如何使用了
先看简单的吧 xaml.cs 中使用:
代码如下 | 复制代码 |
if (m_statusVM.LoadComand.CanExecute(null)) { m_statusVM.LoadComand.Execute(null); } |
这里该是什么参数就在CanExecute 和 Execute 里面传什么参数
如果想在xaml 中绑定command 的话 需要使用Trigger 将Command和控件事件绑定起来:
代码如下:
代码如下 | 复制代码 |
在这里 当Image 的Tap 事件触发的时候 调用 ClickUserCommand 事件 这个Command 没有参数传入。
注意 i是:
代码如下 | 复制代码 |
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" |
工程需要引用 Microsoft.Expression.Interactions
如果需要传入参数 那么代码如下:
代码如下 | 复制代码 |
|
注意这里的Command: 的定义是
xmlns:Command="clr-namespace:WeiFan.Utility.Command;assembly=WeiFan.Utility" 该namespace是DelegateCommand 、CommandArg 和 ComandArgs 的定义所在位置
这里我们想ClickUserCommand 中 CommandArgs 集合对象 集合中有两个CommanArg元素 key 分别为1 和2 .