以前的做法:
1.当项目的时间比较紧迫的时候,对UI层中控件的事件的处理,往往采取的是类似Winform中最简单的做法,直接做一个事件的Handler直接去调用VM层的方法。
2.控件只有一个Command属性,其它的事件的处理方法没有办法和ViewModel层进行解耦的时候往往也采取上面提到的方法。
如下图所示:
新的做法:
为了实现事件的处理与View层的解耦,我们可以利用WPF提供的附加属性来为需要的事件添加附加行为。附加属性扮演了一个在View层与Model层牵线的角色。
需要下面三个步骤来实现(以Load事件为例):
1.在ViewModel中定义一个Command属性
winloadedCommand = new DelegateCommand(this.executeWinloadedCommand, this.canWinloadedCommand);
实例化Command
定义ICommand类型的command
#region
private ICommand winloadedCommand;
public ICommand WinloadedCommand
{
get { return winloadedCommand; }
set
{
if (winloadedCommand != value)
{
winloadedCommand = value;
OnPropertyChagned("WinloadedCommand");
}
}
}
private void executeWinloadedCommand()
{
CalculatingStatus = "The WinloadedCommand has been called!";
}
private bool canWinloadedCommand()
{
return true;
}
#endregion
WinloadedCommand
2.定义一个CommandBehaviors类,在其中定义一个ICommand类型的附加属性,并在PropertyChangedCallback的回调中链接事件与实际的command实例之间的调用。
public static class CommandBehaviors
{
public static ICommand GetWindowLoadCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(WindowLoadCommandProperty);
}
public static void SetWindowLoadCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(WindowLoadCommandProperty, value);
}
// Using a DependencyProperty as the backing store for WindowLoadCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WindowLoadCommandProperty =
DependencyProperty.RegisterAttached("WindowLoadCommand", typeof(ICommand), typeof(CommandBehaviors), new PropertyMetadata(null, OnWindowLoadedCommandPropertyChanged));
public static void OnWindowLoadedCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var frameworkElement = d as FrameworkElement;
if (frameworkElement != null && e.NewValue is ICommand)
{
frameworkElement.Loaded
+= (obj, args) =>
{
if ((e.NewValue as ICommand).CanExecute(obj))
{
(e.NewValue as ICommand).Execute(null);
}
};
}
}
}
CommandBehaviors
3.在xaml中进行Binding
大功告成,运行示例如下:
思考1:如何实现带有参数的调用?Event-〉Command
1.如果参数数据来源于控件本身的属性,可以在链接Event与Command时直接传递参数
2.如果数据来自外界,可以在CommandBehaviors类中定义额外的附加属性,然后将参数绑定到此属性上面,当调用command时,检查该属性。
完毕。
作者:Andy Zeng
欢迎任何形式的转载,但请务必注明出处。
http://www.cnblogs.com/andyzeng/p/3708276.html
WPF系列之二:解耦View层控件事件与ViewModel层事件的响应,布布扣,bubuko.com