DataRepeater doesnt update when changing bound data

1.2k views Asked by At

I have a DataRepeater1 with Label1 and Button1 on the ItemTemplate. These three controls are bound to a BindingList(Of T) where T is, atm, a very simple class that has a single string property

When a user clicks one of the DataRepeater Item's button it updates the string in the bound data list. I.E. If the user clicks the button on item 0 in the DataRepeater, the string in the BindingList at the same index is changed.

This works

What doesn't work is subsequent to the string change the DataRepeater should update Label1 for the relevant item as it is bound to that string - but it doesn't.

Can anyone tell me why?? My current code is below. Thanks

Imports System.ComponentModel

Public Class Form1
    Class ListType
        Public Sub New(newString As String)
            Me.MyString = newString
        End Sub
        Public Property MyString As String
    End Class
    Dim MyList As New BindingList(Of ListType)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Bind BindingList to DataRepeater.
        Label1.DataBindings.Add("Text", MyList, "MyString")
        DataRepeater1.DataSource = MyList

        ' Add some items to the BindingList.
        MyList.Add(New ListType("First"))
        MyList.Add(New ListType("Second"))
        MyList.Add(New ListType("Third"))
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' Use the Index of the current item to change the string 
        '  of the list item with the same index.
        MyList(DataRepeater1.CurrentItemIndex).MyString = "Clicked"

        ' Show all the current list strings in a label outside of 
        '  the DataRepeater.
        Label2.Text = String.Empty
        For Each Item As ListType In MyList
            Label2.Text = Label2.Text & vbNewLine & Item.MyString
        Next
    End Sub
End Class
2

There are 2 answers

0
Toby On BEST ANSWER

Hmmm, it seems odd but after some further experimentation I found that instead of changing the string directly, creating a copy of the object, changing the string and making the object at the concerned index equal to the copy works.

Such as:

    Dim changing As ListType = MyList(DataRepeater1.CurrentItemIndex)
    changing.MyString = "Clicked"
    MyList(DataRepeater1.CurrentItemIndex) = changing

Or a shorter version:

    MyList(DataRepeater1.CurrentItemIndex).MyString = "Clicked"
    MyList(DataRepeater1.CurrentItemIndex) = MyList(DataRepeater1.CurrentItemIndex)

Seems like the BindingList somehow only notifies the DataRepeter when the entire object changes rather than a member of an object...

0
Kirk Larkin On

Take a look at INotifyPropertyChanged:

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

It's using this mechanism that the BindingList class is able to push updates for individual objects to the DataRepeater.

If you implement the INotifyPropertyChanged interface in T, the BindingList will be notified of any changes to T and forward them on to the DataRepeater for you. You just have to raise the PropertyChanged event whenever a property is changed (in the setters of T's properties).

The .NET Framework docs have a walkthrough on using this approach.