Listbox Items Do Not Refresh

smurphy

New member
Joined
Jan 15, 2010
Messages
2
Programming Experience
5-10
I am adding an object to a Listbox which has the properties "ID" and "Text". I have set the "DisplayMember" property of the Listbox to "Text" and "ValueMember" to "ID".

Everything works fine when I add a new item to the list, but when I edit the item and change the "Text" value, it is changing in the object but the Listbox still just showes the original value.

I have tried calling ".Refresh" and ".Update" to see if they worked, but made no difference.

I usually use VB6 for prototyping programs but decided to use VB.NET for this one. Did not realise VB.NET got shot of the "ItemData" property in the ListBox control. Can see the benifit other than this refreshing problem.
 
To support two-way data binding you have to bind to a list that implements IBindingList, such as the BindingList(Of T). In addition the objects must notify property changes by implementing INotifyPropertyChanged interface.

Here's a sample Test class:
VB.NET:
Imports System.ComponentModel

Public Class Test
    Implements INotifyPropertyChanged

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged

    Private _id As Integer
    Public Property Id() As Integer
        Get
            Return _id
        End Get
        Set(ByVal value As Integer)
            If _id <> value Then
                _id = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Id"))
            End If
        End Set
    End Property

    Private _text As String
    Public Property Text() As String
        Get
            Return _text
        End Get
        Set(ByVal value As String)
            If _text <> value Then
                _text = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Text"))
            End If
        End Set
    End Property

End Class
Creating the initial list
VB.NET:
Dim list As New BindingList(Of Test)
and binding it:
VB.NET:
Me.ListBox1.DisplayMember = "Text"
Me.ListBox1.ValueMember = "Id"
Me.ListBox1.DataSource = list
add some objects:
VB.NET:
Dim t As New Test
t.Id = 0
t.Text = "text 0"
list.Add(t)

t = New Test
t.Id = 1
t.Text = "text 1"
list.Add(t)
This code get the selected item and changes the Text:
VB.NET:
Dim t As Test = CType(Me.ListBox1.SelectedItem, Test)
t.Text = "new text"
Later when adding items you have to add them to the BindingList, not the ListBox. If you declared the BindingList as a class member it would be easier available:
VB.NET:
Private list As New BindingList(Of Test)
You can then from different methods use it directly as in the usage samples. Otherwise it is also possible to retrieve it back from the DataSource property, but you'd have to cast it to correct type:
VB.NET:
Dim list As BindingList(Of Test) = CType(Me.ListBox1.DataSource, BindingList(Of Test))
 
Seems like a lot of code for implementing itemdata, but guess the pros outweight the cons with VB.NET vs VB6.

Thanks very much for the solution :)
 
Hmm, there is no 'lots of code' in what I posted. Supposedly the only difference from what you were doing is placing the items in a BindingList and the INotifyPropertyChanged implementation. Nothing really.
 
Back
Top