的双向绑定:
public void BindDataControls(Control.ControlCollection controls)
{
var dataControls = MyWinForm.GetIBControls(controls);
foreach (IDataControl control in dataControls)
{
//control.LinkObject 这里都是 "DataContext"
object dataSource = GetInstanceByMemberName(control.LinkObject);
if (control is TextBox)
{
((TextBox)control).DataBindings.Add("Text", dataSource, control.LinkProperty);
}
if (control is Label)
{
((Label)control).DataBindings.Add("Text", dataSource, control.LinkProperty);
}
if (control is ListBox)
{
((ListBox)control).DataBindings.Add("SelectedValue", dataSource, control.LinkProperty, false, DataSourceUpdateMode.OnPropertyChanged);
}
}
}
另外,我们可能还需要将 一些命令绑定到视图上,而要实现此功能也比较简单:
private Dictionary<object, CommandMethod> dictCommand;
public delegate void CommandMethod();
public void BindCommandControls(Control control,CommandMethod command)
{
if (control is Button)
{
dictCommand.Add(control, command);
((Button)control).Click += (sender, e) => {
dictCommand[sender]();
};
}
}
经过这样的过程后,我们仅需要在窗体加载事件上写下面的几行代码就行了:
SubmitedUsersViewModel DataContext{get;set;}
private void Form1_Load(object sender, EventArgs e)
{
base.BindDataControls(this.Controls);
base.BindCommandControls(this.button1, DataContext.SubmitCurrentUsers);
base.BindCommandControls(this.button2, DataContext.UpdateUser);
base.BindCommandControls(this.button3, DataContext.RemoveUser);
}
上面的代码中,首先定义了一个视图模型对象 DataContext,在方法 BindDataControls 里面作为绑定到视图控件上的对象,它里面的 CurrentUser属性的Name属性绑定到了文本框控件上,所以 CurrentUser.Name 是作为复合属性来绑定的,对于标签控件和列表框控件,也是类似的过程,如下图:
这样,在视图上做简单的数据属性设置和写少量的code behind绑定代码,一个具有双向绑定功能的程序就好了。
MVVM示例解决方案
解决方案概览
为了向大家演示SOD框架对于MVVM的支持,我们搭建一个简单的解决方案,一共分为三个项目程序集,分别对应MVVM的三大部分:
WinFormMvvm: WinForm 示例程序主程序,视图类所在程序集
WinFormMvvm.Model: 模型类程序集
WinFormMvvm.ViewModel: 视图模型程序集
搭建好的解决方案图如下:
注意:此解决方案是使用SOD Ver 5.5.5.1019 做的,因为这是目前nuget 上SOD的版本,最新的SOD框架已经把WinFormMvvm项目的 MvvmForm.cs 文件纳入到框架之内了。
程序在App.config中指定了本次附加测试的数据库,数据库类型为 Access,默认的连接字符串可能要求Office 2007以上版本支持。
下面是App.config 的内容:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name ="default" connectionString ="Provider=Microsoft.ACE.OLEDB.12.0;Jet OLEDB:Engine Type=6;Data Source=testdb.accdb" providerName="Access"/>
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="PWMIS.Core" publicKeyToken="17ba13a12b9fd814" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.5.5.1019" newVersion="5.5.5.1019" />
</dependentAssembly>
</assemblyBinding>
</runtime