F# 与 WPF 之多语言实现MVVM(一)
下面主要介绍如何使用多语言方法实现WPF的MVVM设计模式。我计划分为三篇来介绍多语言方法实现MVVM模式,这是第一篇。
对Visual Studio家族而言,F#是个新成员,但是它的简洁深深地吸引了我。F#在简化并行和异步编程、数据处理和金融建模等复杂问题声誉卓越,而且越来越受欢迎。F#构建MVVM应用程序有两种常用的方法,一种是全F#语言方法,另一种是多语言方法,即用C# + Xaml构建View层,F#负责ViewMode 和Mode层。对于第一种,使用VS的扩展模板很容易办到。我这里只说第二种方法,当然这种方法也是F#团队推荐的方法。其次,C#中针对WPF和Silverlight的工具支持比F#要强大得多。最后,这个种方法也允许我们将F#整合到现有的程序中,降低了再MVVM应用程序中使用F#的风险。
首先,使用WPF应用程序模板在C#中创建一个新的WPF项目,这个项目负责应用程序的视图层
然后,在解决方案中添加一个新的F#库项目,用来保存视图模型(ViewMode)、模型(Mode)和其他非视图代码。
最后,在C#的WPF项目中添加对F#库项目的引用。如此就完成了,开始一个用多语言方法实现MVVM引用程序的设置。
由于这是第一篇,所以这里进行简化处理。这里将使用WPF 提供 ObservableCollection(T) 类,它实现 INotifyCollectionChanged 接口,ObservableCollection(T)表示绑定动态的数据集合,当添加,移除或者刷新整个列表时,该集合会提供通知,此时View层将有机会同步更新数据。
F#库项目中,添加相应的DLL应用,这里请查看我的上一篇博文http://www.cnblogs.com/xiwang/archive/2012/07/11/2586395.html
首先给F#库项目中添加相应的命名空间,和打开相应的命名空间:
namespace Library open System.Windows.Input open System.Collections.ObjectModel open System open System.Windows
为给Button添加Command绑定,所以需要实现自定义的命令,该命令实现Icommand接口。类采用F#的隐式方法定义,如此更简洁,但功能没有显示定义方法的强大。代码如下:
type RelayCommand (_execute : Action<obj>) = interface ICommand with member x.CanExecute (obj) = true member x.Execute(obj) =_execute.Invoke(obj) member x.add_CanExecuteChanged (obj) =() member x.remove_CanExecuteChanged (obj) = ()
这里为简化处理,Mode 之间使用基础类型int。这里实现ViewMode层,该类表示一个班级,只读属性People集合保存班级同学的年龄,_people为字段,这些let绑定表达式,会在类的隐式构造函数中执行:
type ClassViewMode ()= let rnd = Random() let _people=ObservableCollection [0 .. 10] let tick (obj) = let idx =rnd.Next(0,10) _people.[idx] <- _people.[idx] + 1 let cmd= RelayCommand(Action<obj> tick) member x.People with get() = _people member x.Cmd with get() = cmd
如此,ModeView层就完成了,现在需要的是处理视图层,在View中添加一个List控件,ItemsSource 绑定到People属性,添加一个Button,Command属性绑定到Cmd。并在后台新建一个PopleViewMode的实例,并将其作为窗体的数据上下文。如此,在每单击一次Button时,列表中的项,会随即被选择一项,并将其绑定的值加1。
View层的Xaml代码如下:
<Grid> <ListBox ItemsSource="{Binding People}" Margin="0,0,220,76" /> <Button Command="{Binding Cmd}" Margin="303,100,100,173" Content="开始"/> </Grid>
View层的后台代码如下:
public MainWindow() { InitializeComponent(); Library.ClassViewMode vm = new Library.ClassViewMode(); this.DataContext = vm; }
如此,就实现了一个简单的MVVM应用程序。以后再写实现INotifyPropertyChanged接口,以及实现可接受命令绑定的CommboBox