您的位置:首页 > 其它

WPF中的MVVM模式:View与ViewModule的交互个人总结

2010-07-29 11:12 417 查看
出处:/article/5494215.html

在MVVM模式中,viewer负责向用户展示软件设计意图,以期获得最佳的用户体验。VM则负责实现(一定的)业务逻辑,响应Viewer要求,达到隔离业务逻辑的目的。在实际开发中,两者如何进行交互往往是比较头痛的事情。现将开发中用到的交互方法总结一下:
一、使用Binding Command
利用Command是最常用的手段,因为在软件设计中,软件功能的触发往往是由一些具有Command属性的控件实现的,比如buttonbase、meumItem。在这里推荐一种比较实用的ICommand,代码如下:
该Command可以在响应命令前通过CanExecute方法判断是否该命令有效。但是这种command只适用于具有Command属性的ElementFrame。如果没有,则不能进行Binding。

1 public class RelayCommand<T> : ICommand
2 {
3 #region Fields
4
5 readonly Action<T> _execute = null;
6 readonly Predicate<T> _canExecute = null;
7
8 #endregion
9
10 #region Constructors
11 /// <summary>
12 /// 构造函数
13 /// </summary>
14 /// <param name="execute"> 执行逻辑,实际执行函数</param>
15 public RelayCommand(Action<T> execute)
16 : this(execute, null)
17 {
18 }
19 public RelayCommand(Action<T> execute, Predicate<T> canExecute)
20 {
21 if (execute == null)
22 throw new ArgumentNullException("execute");
23
24 _execute = execute;
25 _canExecute = canExecute;
26 }
27
28 #endregion
29
30 #region ICommand Members
31 public bool CanExecute(object parameter)
32 {
33 return _canExecute == null ? true : _canExecute((T)parameter);
34 }
35
36 public event EventHandler CanExecuteChanged
37 {
38 add
39 {
40 if (_canExecute != null)
41 CommandManager.RequerySuggested += value;
42 }
43 remove
44 {
45 if (_canExecute != null)
46 CommandManager.RequerySuggested -= value;
47 }
48 }
49
50 public void Execute(object parameter)
51 {
52 _execute((T)parameter);
53 }
54
55 #endregion
56 }
57
58 /// <summary>
59 ///
60 /// </summary>
61 public class RelayCommand : ICommand
62 {
63 #region Fields
64
65 readonly Action _execute;
66 readonly Func<bool> _canExecute;
67
68 #endregion
69
70 #region Constructors
71
72 /// <summary>
73 /// 构造函数
74 /// </summary>
75 /// <param name="execute">实际执行函数</param>
76 public RelayCommand(Action execute)
77 : this(execute, null)
78 {
79 }
80
81 public RelayCommand(Action execute, Func<bool> canExecute)
82 {
83 if (execute == null)
84 throw new ArgumentNullException("execute");
85
86 _execute = execute;
87 _canExecute = canExecute;
88 }
89
90 #endregion
91
92 #region ICommand Members
93
94 public bool CanExecute(object parameter)
95 {
96 return _canExecute == null ? true : _canExecute();
97 }
98
99 public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
CommandManager.RequerySuggested += value;
}
remove
{
if (_canExecute != null)
CommandManager.RequerySuggested -= value;
}
}

public void Execute(object parameter)
{
_execute();
}

#endregion
}
二、使用Binding Property
绑定属性的方法通常用于实施获取界面某个值的变化,配合Binding的Converter和ValidationRule可以很好的效果,不过在VM中要实现INotifyPropertyChanged,集合通常要实现ObservableCollection<T>。
三、使用Attatch Property
Attatch方法通常是为了VM能够与V通过binding的方法响应一些非Command的事件,比如WindowClose,OnResized等。实现的主要思路是,自定义一个静态类,该类中定义一个AttatchProperty实现,
在XAML文档中对要施加事件的Element的Style中使用Setter进行设置(类似的方法都行,只要附加该自定义AttatchProperty属性就行)。同时在定义的类中,AttachProperty属性注册附加属性当中的属性原数据响应函数中要将DependencyObject对象的特定事件与你的响应函数进行链接。代码如下:

自定义属性
public static readonly DependencyProperty OnWindowCloseActionProperty =
DependencyProperty.RegisterAttached(
"OnWindowCloseAction",
typeof(object),
typeof(MainWindowBehavior),
new UIPropertyMetadata(null, OnHostWindowClose));

private static void OnHostWindowClose(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MainWindow mainWindow = d as MainWindow;
if (null != mainWindow)
mainWindow.Closed += new EventHandler(mainWindow_Closed);

}

static void mainWindow_Closed(object sender, EventArgs e)
{
MainWindow mainWindow = sender as MainWindow;
if (null != mainWindow)
{
MainWindowPresenter tempPresenter = mainWindow.DataContext as MainWindowPresenter;
if (null != tempPresenter)
tempPresenter.Dispose();
}
}

写到最后:
上面三种方法都是本人平时开发过程中经常使用的方法,基本可以满足大部分的需要。如果有进一步的需求,可以关注一下http://caliburn.codeplex.com/。类似于Message.Attach="[Event Click] = [Action Divide]"的形式就可以实现命令的链接了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: