However, I set up a loop that iterates the List of Type (myThingList) and updates each property in myThingList. After the loop completes the bound text control does not show the new value, it does not display the actual value that is in myThingList I have to BindingSource.MovePrevious() then BindingSource.MoveNext() before the text control displays the correct values, the actual values that are in myThingList.
Is there a way to force (changes that are made to property values in myThingList) so they are automatically reflected in the bound Textbox?
Binding works by raising and handling events, just like everything else. In order for the
Binding to update the control when you make changes to the data source (add, delete or set item) the data source has to raise events when those changes happen, which the
List(Of T) class does not. In order for the
Binding to update the control when you make changes to the current item, the item class has to raise an event when the bound property changes, which no class does by default. If you want bindings to update automatically then you need you data source and the items it contains to raise those events. That would mean at least using a
BindingList(Of T) rather than a
List(Of T) and it would also mean changing the implementation of your item class. For instance, instead of this:
Public Class Thing
Public Property Stuff As String
End Class
you would need this:
Public Class Thing
Private _stuff As String
Public Property Stuff As String
Get
Return _stuff
End Get
Set
If _stuff <> value Then
_stuff = value
OnStuffChanged(EventArgs.Empty)
End If
End Set
End Property
Public Event StuffChanged As EventHandler
Protected Overridable Sub OnStuffChanged(e As EventArgs)
RaiseEvent StuffChanged(Me, e)
End Sub
End Class
or this:
Imports System.ComponentModel
Public Class Thing
Implements INotifyPropertyChanged
Private _stuff As String
Public Property Stuff As String
Get
Return _stuff
End Get
Set
If _stuff <> value Then
_stuff = value
OnPropertyChanged(New PropertyChangedEventArgs(NameOf(Stuff)))
End If
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(e As PropertyChangedEventArgs)
RaiseEvent PropertyChanged(Me, e)
End Sub
End Class
If you implement
INotifyPropertyChanged then you can use the one event for multiple properties. Otherwise, you need to declare an event for each property that you want to bind separately and each event MUST be named after the associated property with the suffix "Changed". The
Binding will look for that name specifically.
If you don't want to make those changes then you can use the
BindingSource to force changes to the bound control, which is another reason to use one. If you make changes to the currently selected item then you can call
ResetCurrentItem. That will do what you were were doing by calling
MovePrevious and MoveNext. If you make changes to a different item then you can call
ResetItem. You can also make multiple changes or changes to the list itself and then call
ResetBindings.