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]"的形式就可以实现命令的链接了。
在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]"的形式就可以实现命令的链接了。
相关文章推荐
- wpf中使用MVVM模式进行开发,View与ViewModule的交互个人总结
- WPF学习笔记:MVVM模式下,ViewModel如何关闭View?
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
- WPF中通过MVVM模式来关闭View
- WPF:MVVM模式下ViewModel关闭View
- WPF MVVM模式总结
- WPF学习笔记:MVVM模式下,ViewModel如何关闭View?
- MVVM模式下ViewModel之间如何交互
- WPF中通过MVVM模式来关闭View
- WPF学习笔记:MVVM模式下,ViewModel如何关闭View?
- WPF 加UserControl(wpf) ViewModel模式数据之间交互
- WPF MVVM设计模式的ViewModelBase和CommandBase代码
- 笔记03 wpf 在MVVM模式下怎样在Viewmodel里面获得view的控件对象
- wpf首次项目开发总结之人机交互模式
- 单列模式,RecyclerView适配器封装,BroadcastReceiver介绍,Mvp+Retrofit+rxjava+okhttp框架的梳理总结
- [译]WPF 应用程序和MVVM设计模式 ——Josh Smith
- Android学习WebView交互开发总结
- Prism初研究之使用Prism实现WPF的MVVM模式
- WPF MVVM中在ViewModel中关闭或者打开Window
- WPF/Silverlight中的MVVM模式能否在WinForm/ASP.NET上运用?