DataTable绑定TextBox时DBNull异常仅触发一次的解决咨询
解决DataTable绑定后重复验证不触发异常的问题
我之前也碰到过一模一样的情况,这其实是.NET数据绑定机制的默认行为在搞鬼。咱们先理清楚原因,再给你几个可行的解决办法:
为什么第二次调用不会触发异常?
当你第一次调用CurrencyManager.EndCurrentEdit()时,因为C1为空违反了AllowDBNull=false的约束,验证失败抛出异常。这时候CurrencyManager会进入挂起编辑状态,并且自动保存了编辑前的原始行数据快照。第二次调用EndCurrentEdit()时,它会直接用这个快照里的旧值(也就是之前的"Column 1 Value")来恢复,根本不会再去读取文本框的当前空值,自然就不会触发异常了。
解决办法
方法1:每次验证前重新开启编辑状态
在调用EndCurrentEdit()之前,先调用BeginCurrentEdit(),强制CurrencyManager重新读取文本框的当前值,覆盖之前的快照:
Try ' 重新开启编辑流程,强制读取控件当前值 CurrencyManager.BeginCurrentEdit() CurrencyManager.EndCurrentEdit() Catch ex As Exception MsgBox("The field C1 can not be empty") End Try
这样每次验证都会基于文本框的最新内容,空值的话就会触发预期的异常。
方法2:手动同步控件值到数据源
如果你想更直接地控制数据流向,可以手动把文本框的内容同步到DataRow,再执行验证:
Try ' 手动将TextBox1的当前值同步到C1列 Dim currentRow As DataRowView = CType(CurrencyManager.Current, DataRowView) currentRow("C1") = TextBox1.Text CurrencyManager.EndCurrentEdit() Catch ex As Exception MsgBox("The field C1 can not be empty") End Try
这种方式绕开了绑定的自动快照机制,直接用控件的最新值去验证。
方法3:给DataTable添加列级验证(更推荐)
如果想从根源上把控验证逻辑,给DataTable添加ColumnChanging事件,只要C1列的值被修改就触发检查,不管是通过绑定还是直接修改行数据:
' 在创建DataTable之后添加这个事件处理 AddHandler DT.ColumnChanging, AddressOf DT_ColumnChanging ' 事件处理方法 Private Sub DT_ColumnChanging(sender As Object, e As DataColumnChangeEventArgs) If e.Column.ColumnName = "C1" Then ' 检查新值是否为空或空字符串 If e.ProposedValue Is DBNull.Value OrElse String.IsNullOrEmpty(CStr(e.ProposedValue)) Then Throw New Exception("The field C1 can not be empty") End If End If End Sub
这样只要C1被设置为空,立刻就会抛出异常,不需要依赖EndCurrentEdit()的调用,验证逻辑更可靠。
内容的提问来源于stack exchange,提问作者Thomas Carlton
相关产品推荐
相关产品推荐

