How to bind TextBox.Text property to a List (Of Type)?

BrettNelson

Member
Joined
Apr 8, 2016
Messages
11
Programming Experience
Beginner
Can anyone point me the right direction?

I'm trying to bind a TextBox.Text property to a property in a list of objects.

Does anyone know where I can read or see examples of binding a Text property to a property in a List Of Type?
 
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:
VB.NET:
BindingSource1.DataSource = myThingList
TextBox1.DataBindings.Add("Text", BindingSource1, "Stuff")
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.
 
A List works fine with INotifyPropertyChanged for simple textbox binding, but if you bind to a DataGridView you need a BindingList.
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.
And where the NameChanged event works for textbox binding, a DataGridView requires INotifyPropertyChanged.
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.

Are you sure about that?
Yes, it will only detect change of current item otherwise.
 
Back
Top