There is a very nice article on MSDN explaining this;
http://msdn.microsoft.com/en-us/library/ms229603.aspx
It clearly states, "When you use data binding, the data in your control is synchronized with the data source during execution of the Validating event. If you cancel the Validating event, the data will not be synchronized with the data source."
So I've created a tiny example application called NoSourceUpdate, which basically contains a list of some data, an ID and a Name. I create the list, and bind it to a listbox, then bind the textboxes to the list's properties. There are also 2 lables bound to the list to reflect the internal list's values to demonstate the problem I'm having.
Expand|Select|Wrap|Line Numbers
- Public Class Form1
- Private errorlist As New ErrorProvider
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- Dim DataList As New List(Of Data)
- Dim NewData As New Data
- NewData.ID = 1
- NewData.name = "Name One"
- DataList.Add(NewData)
- NewData = New Data
- NewData.ID = 2
- NewData.name = "Name Two"
- DataList.Add(NewData)
- Dim ListBinder As New BindingSource
- ListBinder.DataSource = DataList
- ListBox1.DataSource = ListBinder
- ListBox1.DisplayMember = "Name"
- TextBox1.DataBindings.Add("Text", ListBinder, "Name")
- TextBox2.DataBindings.Add("Text", ListBinder, "ID")
- Label1.DataBindings.Add("Text", ListBinder, "Name")
- Label2.DataBindings.Add("Text", ListBinder, "ID")
- End Sub
- Private Sub TextBox1_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
- If (sender.text.length < 5) Then
- e.Cancel = True
- errorlist.SetError(sender, "Name is too short!")
- Else
- errorlist.SetError(sender, "")
- End If
- End Sub
- End Class
- Public Class Data
- Private myName As String
- Public Property name() As String
- Get
- Return myName
- End Get
- Set(ByVal value As String)
- myName = value
- End Set
- End Property
- Private myID As Integer
- Public Property ID() As Integer
- Get
- Return myID
- End Get
- Set(ByVal value As Integer)
- myID = value
- End Set
- End Property
- End Class
You can see a screenshot of what is happening here;
http://imagebin.org/index.php?mode=image&id=26163
Clearly I am misunderstanding how this works. Canceling the validating event traps the users focus on the invalid textbox, which is great. It also stops the validated event from firing, also great. However, the invalid data is still syncronized to the data source which is causing all sorts of exceptions being thrown. Sure I could code another level of validation into the data class, but then why does the validating event exist? Why is the data still being syncronized when I cancle the validating event?
Can somebody please explain to me what I am doing wrong, or at least show me how to do this properly?
Thanks!
Diff