How to stop a custom control bound to a business object from updating unnecessarily?
I have a Windows Forms application with a custom control for entering dates. This is inherits from Textbox and implements a Value property for binding to the underlying business object.
Everything works well except that when the control validates it updates the bound property, even when it hasn't changed. This is a problem because I'm using Entity Framework and the change to the entity's property causes the corresponding field in the database to be updated every time a user opens and close开发者_开发百科s the form hosting this control.
Here is the code:
Public Class TextBoxDate
Inherits TextBox
Public ValueChanged As EventHandler
Private _dateValue As Nullable(Of Date) = Nothing
<Bindable(True)> _
<Category("Appearance")> _
Public Property Value() As Nullable(Of Date)
' Bind to the Value property instead of the Text property, as the latter will not allow
' the user to delete the contents of the textbox. The Value property provides support for nulls.
Get
Value = _dateValue
End Get
Set(ByVal value As Nullable(Of Date))
_dateValue = value
' Update the text in the textbox
If value.HasValue Then
Text = CDate(value).ToShortDateString
Else
Text = vbNullString
End If
OnValueChanged()
End Set
End Property
Private Sub OnValueChanged()
If (ValueChanged IsNot Nothing) Then
ValueChanged(Me, New EventArgs())
End If
End Sub
Private Sub TextBoxDate_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Enter
_userEntered = True
End Sub
Private Sub TextBoxDate_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Leave
_userEntered = False
End Sub
Protected Overrides Sub OnValidating(ByVal e As System.ComponentModel.CancelEventArgs)
If _userEntered Then
If Me.TextLength = 0 Then
' Null value will be saved to the database via the bound Value property
If Value IsNot Nothing Then
Value = Nothing
End If
Else
Dim dateValue As Date
If Date.TryParseExact(Text, "d/M/yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, Globalization.DateTimeStyles.None, dateValue) Then
If Value Is Nothing Or (dateValue <> Value) Then
Value = CDate(Text)
End If
Else
e.Cancel = True
End If
End If
End If
MyBase.OnValidating(e)
End Sub
End Class
This is driving me mad. Any help would be much appreciated.
Scott
When you define the binding of the textbox you can specify the DataSourceUpdateMode of the Binding object, for example
Binding custNameBinding = new Binding("Text", ds, "customers.custName");
custNameBinding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
custNameTextBox.DataBindings.Add(custNameBinding);
The MSDN documentation says "Data source is updated whenever the value of the control property changes."
精彩评论