views:

820

answers:

1

Hello,

I'm working in VB.NET

I have an ArrayList named Invoices populated with objects of the class Invoice.

I'd like to data bind this to a ListBox so that as the contents of the ArrayList are updated and changed the ListBox updates. I've implemented a .ToString function on the Invoice class, I just don't know how I'd go about binding the ArrayList to the ListBox.

Any suggestions?

+2  A: 

I'm going to make the assumption that this is winforms.

If you want two-way data-binding, you need a few things:

  • to detect addition/removal etc, you need a data-source that implements IBindingList; for classes, BindingList<T> is the obvious choice (ArrayList simply won't do...)
  • to detect changes to properties of the objects, you need to implement INotifyPropertyChanged (normally you can use the "*Changed" pattern, but this isn't respected by BindingList<T>)

Fortunately, ListBox handles both of these. A full example follows; I've used C#, but the concepts are identical...

using System;
using System.ComponentModel;
using System.Windows.Forms;
class Data : INotifyPropertyChanged{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; OnPropertyChanged("Name"); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this,
            new PropertyChangedEventArgs(propertyName));
    }
}
static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Button btn1, btn2;
        BindingList<Data> list = new BindingList<Data> {
            new Data { Name = "Fred"},
            new Data { Name = "Barney"},
        };
        using (Form frm = new Form
        {
            Controls =
            {
                new ListBox { DataSource = list, DisplayMember = "Name",
                     Dock = DockStyle.Fill},
                (btn1 = new Button { Text = "add", Dock = DockStyle.Bottom}),
                (btn2 = new Button { Text = "edit", Dock = DockStyle.Bottom}),
            }
        })
        {
            btn1.Click += delegate { list.Add(new Data { Name = "Betty" }); };
            btn2.Click += delegate { list[0].Name = "Wilma"; };
            Application.Run(frm);
        }
    }
}
Marc Gravell