ComboBox binding to subset of another ComboBox

G

Guest

This is for a Windows Forms application...

I am wanting to set up binding once, if possible, for a second combobox that
contains filtered data based on the first.

I know I can capture the event of the first combobo and then bind the second
based on the value, but was hoping that there is an easier/better way.


Here is the scenario


class Car
{
Guid carID;
int year;
string carName;
}

class Manufacturer
{
Guid id;
string name;
List<Car> cars;
}

class MyCollection
{
List<Manufacturer> makers;
}


private void MyControl_Load( object sender, EventArgs e )
{
cboMaker.DisplayMember = "Name";
cboMaker.ValueMember = "ID";
cboMaker.DataSource = makers;

cboCar.DisplayMember = "CarName";
cboCar.ValueMember = "CarID";
cboCar.DataSource = ??? <<<<<<<<<<<<<<<<
}


Thanks,
Dave
 
S

Stoitcho Goutsev \(100\)

Webber,



What you want to do is master-detail type of data binding. I don't think
there is an easier way of doing it with comboboxes and a list object, but I
believe there is certainly a better way of doing it. That is instead of
hooking to the combobox events you should use the binding context and the
currency manager. To demonstrate how it is different I'm posting a test
application. Just create a windows forms test application, drop 2 conboboxes
one datagridview and one list box on the form. Then copy and paste the
posted form class in your form's *cs* file.

now change the manufacturer from the combobox and observer how all the
components gets updated correctly. You can change the manufacturer from
either of the controls and it will update the others.

This is a simple example and one can argue that this all will work even if
simply hooking to the manufacturer combobox event, but in some more complex
application this implementation could provide more flexibility first because
all necessary re-binding is done in one place and secondly because this is
how all data binding magic in windows forms works.


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Manufacturer m = new Manufacturer();
m.Name = "Ford";
m.Id = 0;

Car c = new Car();
c.CarName = "Focus";
c.CarID = 0;
c.Year = 2003;
m.cars.Add(c);

c = new Car();
c.CarName = "Mustang";
c.CarID = 1;
c.Year = 1992;
m.cars.Add(c);


makers.Add(m);

m = new Manufacturer();
m.Name = "GMC";
m.Id = 0;

c = new Car();
c.CarName = "Yukon";
c.CarID = 2;
c.Year = 1998;
m.cars.Add(c);

c = new Car();
c.CarName = "Envoy";
c.CarID = 3;
c.Year = 2005;
m.cars.Add(c);
makers.Add(m);



}

public class Car
{
private int carID;

public int CarID
{
get { return carID; }
set { carID = value; }
}
private int year;

public int Year
{
get { return year; }
set { year = value; }
}
private string carName;

public string CarName
{
get { return carName; }
set { carName = value; }
}
}

public class Manufacturer
{
private int id;

public int Id
{
get { return id; }
set { id = value; }
}
private string name;

public string Name
{
get { return name; }
set { name = value; }
}
public List<Car> cars = new List<Car>();
}

ArrayList makers = new ArrayList();



protected override void OnLoad(EventArgs e)
{

comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Id";
comboBox1.DataSource = makers;
CurrencyManager cm = (CurrencyManager)comboBox1.BindingContext[makers];
cm.CurrentChanged += new EventHandler(cm_CurrentChanged);

object detailsDataSource = ((Manufacturer)cm.Current).cars;
comboBox2.DisplayMember = "CarName";
comboBox2.ValueMember = "CarID";
comboBox2.DataSource = detailsDataSource;

this.dataGridView1.DataSource = detailsDataSource;

this.listBox1.DisplayMember = "Name";
this.listBox1.ValueMember = "Id";
this.listBox1.DataSource = makers;

}

void cm_CurrentChanged(object sender, EventArgs e)
{
CurrencyManager cm = sender as CurrencyManager;
object dataSource = ((Manufacturer)cm.Current).cars;
comboBox2.DataSource = dataSource;
this.dataGridView1.DataSource = dataSource;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top