如果我通过设置 DataSourceUpdateMode = Never 关闭绑定数据源的自动更新,然后使用按钮更新整个批次(使用 binding.WriteValue),则会出现问题 - 即,仅更新第一个绑定控件的数据源。所有其他控件都重置为原始值。
这是因为当当前对象发生变化时(如上述WriteValue之后发生的情况),如果ControlUpdateMode = OnPropertyChange,那么所有其他控件都会重新从数据源中读取该值。
避免这个问题的标准方法是什么?
一种方法是从 BindingSource 派生一个类并添加一个 WriteAllValues 方法。此方法执行以下操作:
(1)对于每个Binding,保存ControlUpdateMode
(2) 对于每个Binding,设置ControlUpdateMode = Never
(3) 对于每个Binding,调用WriteValue方法
(4) 对于每个 Binding,将 ControlUpdateMode 重置为保存的值
(5) 对于每个Binding,如果ControlUpdateMode = OnPropertyChange,调用ReadValue方法。
你能看出这样做有什么问题吗?
如果使用您自己的类,实现 IEditableObject 会解决问题吗?
在我正在处理的另一个控件中,我实现了自己的绑定。我解决这个问题的方法是使用以下代码。(我已经做到了最低限度,希望你能遵守!):
Private Shared ControlDoingExplicitUpdate As MyCustomControl = Nothing
Private Sub UpdateDataSourceFromControl(ByVal item As Object, ByVal propertyName As String, ByVal value As Object)
Dim p As PropertyDescriptor = Me.props(propertyName)
Try
ControlDoingExplicitUpdate = Me
p.SetValue(item, value)
Catch ex As Exception
Throw
Finally
ControlDoingExplicitUpdate = Nothing
End Try
End Sub
Private Sub DataBindingSource_CurrentItemChanged(ByVal sender As Object, ByVal e As System.EventArgs)
If (ControlDoingExplicitUpdate IsNot Nothing) AndAlso (ControlDoingExplicitUpdate IsNot Me) Then Exit Sub
Me.UpdateControlFromDataSource() 'Uses ReadValue
End Sub
因此,当调用 UpdateDataSourceFromControl 时,将为同一 BindingSource 中的所有其他控件调用所有 CurrentItemChanged 事件。但是,由于设置了 ControlDoingExplicitUpdate,它们不会从数据源重新读取值,除非它们恰好是进行更新的控件。在所有这些事件完成后,ControlDoingExplicitUpdate 设置为 Nothing,以便恢复正常服务。
我希望你能关注这个,并且 - 再次 - 我问,你能看到这有什么问题吗?