Every control has a DataBindings property and that is where you bind control properties to data source properties. For instance, if you have a List(Of Thing) and the Thing class has a Stuff property that you want to bind and display in TextBox1, your code might look like this:
You don't have to use a BindingSource in between but you generally should. The BindingSource would be added to the form in the designer. Once the list is bound to the BindingSource, you would bind all your controls to that BindingSource. Any selections made in the UI via a DataGridView, ComboBox or some other list control bound to the same data source, your TextBox and other controls will update automatically. You can also navigate using the BindingSource in code or an associated BindingNavigator in the UI.
The BindingSource works very well! Thanks!
I added bindings like TextBox1.Control.DataBindings.Add("Text", BindingSource, "Stuff") to my Text controls. Now I am able to use the BindingSource.MovePrevious() and BindingSource.MoveNext() and the data in my Text controls reflect the value of current index. Any changes, made through the UI,are also applied to the underlying myThingList
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?
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:
VB.NET:
Public Class Thing
Public Property Stuff As String
End Class
you would need this:
VB.NET:
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:
VB.NET:
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.
A List works fine with INotifyPropertyChanged for simple textbox binding, but if you bind to a DataGridView you need a BindingList.
And where the NameChanged event works for textbox binding, a DataGridView requires INotifyPropertyChanged.
It wouldn't matter for adding new items or editing existing items but it would matter for deleting or replacing existing items. If those operations aren't being performed then the list type is unimportant.
Are you sure about that? I didn't think that was the case but that may just have been an assumption that I've never actually tested. I might have to test that out for my own edification.
I only tested changing the property of each item in the list as OP asked about. Adding/removing items with navigator is not a problem with list/textbox binding, since that changes current item in bindingsource, but you should use BindingList if you change underlying list directly.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.