4

This seems like an obvious thing to achieve, but I just can't figure it out. Let's say I have a list of strings. How do I bind it to a listbox so that the listbox updates as the data of the list changes? I'm using vb.net.

I've tried this so far. I've manage to display the data, but not change it:

Public Class Form1

    Private mycountries As New List(Of String)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        mycountries.Add("Norway")
        mycountries.Add("Sweden")
        mycountries.Add("France")
        mycountries.Add("Italy")
        mycountries.Sort()
        ListBox1.DataSource = mycountries 'this works fine

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        mycountries.RemoveAt(0)
        ListBox1.DataSource = mycountries 'this does not update
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        MsgBox(mycountries(0))
    End Sub
End Class

I've also tried this:

ListBox1.DataBindings.Add("items", mycountries, "Item")

But items is readonly, so it doesn't work.

Also, if I want to bind the enabled property of a button to a boolean, how can I do that? I've tried this but I don't know what to add for the last parameter.

Dim b As Boolean = True
Button3.DataBindings.Add("Enabled", b, "")
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
Kritz
  • 7,099
  • 12
  • 43
  • 73

2 Answers2

8

You need to use a collection that supports change notifications for your data source. When you remove an item from a plain list, it doesn't tell anybody about it.

Here's an example of using a BindingList instead:

Public Class Form1

    Private mycountries As New BindingList(Of String)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        mycountries.Add("Norway")
        mycountries.Add("Sweden")
        mycountries.Add("France")
        mycountries.Add("Italy")
        ' BindingList doesn't have a Sort() method, but you can sort your data ahead of time
        ListBox1.DataSource = mycountries 'this works fine

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        mycountries.RemoveAt(0)
        ' no need to set the DataSource again here
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        MsgBox(mycountries(0))
    End Sub
End Class

For your second question, you do not bind to a variable when adding a data binding. You bind to an object (which acts as the data source) and then specify a property on that object that will give you the value you want bind to.

So, for a button, you want something like this (apologies for C#, but you'll get the idea):

public class SomeModel
{
    public bool ButtonEnabled { get; set; }
}
public class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        SomeModel model = new SomeModel();

        // first parameter - button's property that should be bound
        // second parameter - object acting as the data source
        // third parameter - property on the data source object to provide value
        button1.DataBindings.Add("Enabled", model, "ButtonEnabled");
}

In general, databinding is all about change notification. If you need to bind to custom objects, look into the INotifyPropertyChanged interface.

Adam Lear
  • 38,111
  • 12
  • 81
  • 101
  • Perfect! Thank you very much! Are there any performance considerations that i must be aware when using an approach like this compared to changing the button the normal way? – Kritz Sep 09 '11 at 06:59
  • @Johan Not that I know of. I've never seen any impact on performance even on fairly busy forms. Don't forget that you will need to implement `INotifyPropertyChanged` for the property that you're binding to in order for the button's state to be updated when you change the property value. – Adam Lear Sep 09 '11 at 13:44
0

You can do this trick:

ListBox1.DataSource = Nothing
mycountries.RemoveAt(0)
ListBox1.DataSource = mycountries
NaveenBhat
  • 3,248
  • 4
  • 35
  • 48