wpf中使用MVVM模式进行开发,View与ViewModule的交互个人总结(转)
在MVVM模式中,viewer负责向用户展示软件设计意图,以期获得最佳的用户体验。VM则负责实现(一定的)业务逻辑,响应Viewer要求,达到隔离业务逻辑的目的。在实际开发中,两者如何进行交互往往是比较头痛的事情。现将开发中用到的交互方法总结一下:
一、使用Binding Command
利用Command是最常用的手段,因为在软件设计中,软件功能的触发往往是由一些具有Command属性的控件实现的,比如buttonbase、meumItem。在这里推荐一种比较实用的ICommand,代码如下:
该Command可以在响应命令前通过CanExecute方法判断是否该命令有效。但是这种command只适用于具有Command属性的ElementFrame。如果没有,则不能进行Binding。
public class RelayCommand<T> : ICommand { #region Fields readonly Action<T> _execute = null; readonly Predicate<T> _canExecute = null; #endregion #region Constructors /// <summary> /// 构造函数 /// </summary> /// <param name="execute"> 执行逻辑,实际执行函数</param> public RelayCommand(Action<T> execute) : this(execute, null) { } public RelayCommand(Action<T> execute, Predicate<T> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion #region ICommand Members public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute((T)parameter); } public event EventHandler CanExecuteChanged { add { if (_canExecute != null) CommandManager.RequerySuggested += value; } remove { if (_canExecute != null) CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _execute((T)parameter); } #endregion } /// <summary> /// /// </summary> public class RelayCommand : ICommand { #region Fields readonly Action _execute; readonly Func<bool> _canExecute; #endregion #region Constructors /// <summary> /// 构造函数 /// </summary> /// <param name="execute">实际执行函数</param> public RelayCommand(Action execute) : this(execute, null) { } public RelayCommand(Action execute, Func<bool> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion #region ICommand Members public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(); } 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对象的特定事件与你的响应函数进行链接。代码如下: XAML <Window.Style> <Style TargetType="{x:Type Window}"> <Setter Property="Host:MainWindowBehavior.OnWindowCloseAction" Value="{Binding }" /> </Style> </Window.Style> 自定义属性 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]"的形式就可以实现命令的链接了。
链接:http://www.cnblogs.com/oliverxgwang/archive/2009/07/28/1532678.html

浙公网安备 33010602011771号