在数据库应用程序开发中,我们知道数据操作的主要任务是:“浏览、编辑、删除、添加记录”,利用VB.NET的“数据窗体向导”可以帮助我们迅速创建实现上述功能的Windows 窗体及相关代码,这种自动生成的代码完全具有实用性和可借鉴性。然而笔者在使用中发现,在“数据窗体向导”的操作过程中,如果我们选择的是“单个控件的单个记录”显示样式,假如控件绑定到的数据源中的字段又有不允许为Null值的话,运行自动生成的窗体,单击“添加”后会出现错误。
为了避免该错误,已有的解决方法是:“添加”功能不使用“数据窗体向导”生成的代码,而是新建一窗体然后采用非数据绑定结构来单独实现“添加”功能。笔者经过探索发现完全没有必要另建窗体,只需对“数据窗体向导”生成的代码进行适当的改进就可以在同一个窗体中同时实现“浏览、编辑、删除、增加”功能,如下通过实例说明(注:开发工具为Microsoft Visual Studio .NET 2003 ,示例数据库是SQL Server 2000中的“pubs”;以下代码虽然以VB为例,但方法同样适用于VS.NET中的其它开发语言)。
一、 有不允许为Null值的字段绑定到非TextBox类控件
如下图一所示就是属于这类情况,窗体中“contract”旁的复选框控件绑定到的列字段“contract”就不允许有Null值。运行该窗体并“加载”后,单击“添加”可以“新增”记录(编号为24的记录),但单击导航按钮(比如最后一条“>>”),记录位置不能移到该新增记录。
图一窗体及代码是由“数据窗体向导”自动生成(菜单操作:“文件/添加新项”,然后选 “数据窗体向导”),数据窗体实例的名称是“DEMO”,数据集的名称是“DS”,数据连接是以SQL Server 2000中的“pubs” 示例数据库为例,选择“authors”表,选择“单个控件的单个记录”显示样式,其它都采用“数据窗体向导”的默认值。图一这一类情况的改进方法是首先修改“添加”按钮的单击事件处理代码,如下所示。
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Try
Me.BindingContext(objDS, "authors").EndCurrentEdit()
Me.BindingContext(objDS, "authors").SuspendBinding() '临时挂起数据绑定
Me.BindingContext(objDS, "authors").AddNew() '增加新记录
'如下两层循环先找出authors表中不允许为null的列字段,然后找出绑定到该字段的binding对象,
'依据绑定到的控件属性不同来为新增记录中不能为空的字段赋不同初始值
Dim i As Integer
For i = 0 To objDS.authors.Columns.Count - 1 '遍历authors表中所有列字段
'找出authors表中不允许为null的列字段
If objDS.Tables("authors").Columns(i).AllowDBNull = False Then
Dim j As Integer
For j = 0 To Me.BindingContext(objDS, "authors").Bindings.Count - 1 '遍历所有Binding对象
'找出绑定到不允许为null字段的binding对象
If Me.BindingContext(objDS, "authors").Bindings(j).BindingMemberInfo.BindingField = _
objDS.authors.Columns(i).ColumnName Then
'如果绑定到的控件的属性为Text
If BindingContext(objDS, "authors").Bindings(j).PropertyName() = "Text" Then
'新增加记录中不能为null的字段赋初始值"",该语句还可用紧挨着的注释语句代替!
Me.BindingContext(objDS, "authors").Current(j) = ""
'BindingContext(objDS, "authors").Current(i) = BindingContext(objDS, "authors"). _
' Bindings(j).Control.Text()
Exit For '退出当前For循环,寻找下一个不允许为null的列字段
Else
'如果绑定到的控件的属性为Checked(其它绑定属性…,应该可以自己仿照搞定了.)
If BindingContext(objDS, "authors").Bindings(j).PropertyName = "Checked" Then
'新增加记录中不能为null的字段赋初始值True, 该语句可用紧挨着的4行注释语句代替!
Me.BindingContext(objDS, "authors").Current(j) = True
'Dim tmpobj As Object
'tmpobj = BindingContext(objDS, "authors").Bindings(j).Control
'tmpobj = CType(tmpobj, CheckBox)
'Me.BindingContext(objDS, "authors").Current(j) = tmpobj.checked
Exit For '退出当前For循环,寻找下一个不允许为null的列字段
End If
End If
End If
Next
End If
Next
'如新增加行不需利用row_changing事件进行数值验证,可启用下边注释行
'Me.BindingContext(objDS, "authors").EndCurrentEdit()
Me.BindingContext(objDS, "authors").ResumeBinding()