Creating a databound ComboBox

  • Thread starter Thread starter Matt Burland
  • Start date Start date
M

Matt Burland

Okay, I'm having MAJOR problems with this thing. Here's what I'm trying to
do: I have a form which displays information from a database and allows the
user to change it. It contains various controls such as text boxes and
comboboxes. Now, I want to use the comboboxes to restrict the user to
entering only a handful of values into certain fields so I populate the
comboboxes with the allowed values in design mode (e.g. "A","B","C") and
then bind the data source to the combobox. What should happen is that the
string from the database is matched to a value in the ComboBox.Items
collection and that item is displayed in the combobox. When the user changes
the combobox, that value should be passed back to the data source. What I am
NOT doing (and what 95% of databinding with combobox examples seem to do) is
populate a combobox with values from a database.
So I've tried:

MyComboBox.DataBindings.Add(new Binding("Text",MyDataView,"MyField");

That manages to match up the string from MyField with a value in the
combobox. The problem is that the value will not be passed back to the
database if the user changes it.

So I tried:

MyComboBox.DataBindings.Add(new
Binding("SelectedItem",MyDataView,"MyField");

This does match the string to the correct value in the combobox, and changes
get passed back to the database, BUT, the binding somehow causes EVERY
record you look at to be marked as "Modified" regardless of if you touch the
database or not!

So I thought I would create a new class that inherits from ComboBox and give
it an extra property that I could bind to. That way I would be able to
control when and if it gets changed so I tried this:

public class DataComboBox : ComboBox

{

private object bound;

public object Bound

{

get { return bound; }

set

{

if (value.ToString() != bound.ToString())

{

bound = value;

if (this.Items.Contains(bound))

{

this.Text = bound.ToString();

}

else

{

this.Text = "Unknown";

}

//this.OnTextChanged(new EventArgs());

}

}

}

public DataComboBox()

{

//

// TODO: Add constructor logic here

//

bound = this.Name;

}



protected override void OnSelectedIndexChanged(EventArgs e)

{

Bound = this.Items[this.SelectedIndex];

base.OnSelectedIndexChanged (e);

}



and bound to it like this:



MyComboBox.DataBindings.Add(new Binding("Bound",MyDataView,"MyField");



But this still has the same problem as "SelectedItem".

Can anyone please help me out here! I'm getting desperate!!



Cheers



Matt
 
If your combobox contains a set of objects you need to set ValueMember and
bind to selected value:

comboBox1.Items.Add(aState);
comboBox1.ValueMember = "ShortName";
comboBox1.DisplayMember = "LongName";

If you are just bound to a string value simply use Text:

sqlDataAdapter1.Fill(this.customerDataSet1);

foreach(CustomerDataSet.CustomersRow r in
customerDataSet1.Customers) {
comboBox1.Items.Add(r.Region);
}

this.textBox1.DataBindings.Add(new
System.Windows.Forms.Binding("Text", this.customerDataSet1,
"Customers.CustomerID"));
this.textBox2.DataBindings.Add(new
System.Windows.Forms.Binding("Text", this.customerDataSet1,
"Customers.ContactName"));
this.comboBox1.DataBindings.Add(new
System.Windows.Forms.Binding("Text", this.customerDataSet1,
"Customers.Region"));

mark


Matt Burland said:
Okay, I'm having MAJOR problems with this thing. Here's what I'm trying to
do: I have a form which displays information from a database and allows the
user to change it. It contains various controls such as text boxes and
comboboxes. Now, I want to use the comboboxes to restrict the user to
entering only a handful of values into certain fields so I populate the
comboboxes with the allowed values in design mode (e.g. "A","B","C") and
then bind the data source to the combobox. What should happen is that the
string from the database is matched to a value in the ComboBox.Items
collection and that item is displayed in the combobox. When the user changes
the combobox, that value should be passed back to the data source. What I am
NOT doing (and what 95% of databinding with combobox examples seem to do) is
populate a combobox with values from a database.
So I've tried:

MyComboBox.DataBindings.Add(new Binding("Text",MyDataView,"MyField");

That manages to match up the string from MyField with a value in the
combobox. The problem is that the value will not be passed back to the
database if the user changes it.

So I tried:

MyComboBox.DataBindings.Add(new
Binding("SelectedItem",MyDataView,"MyField");

This does match the string to the correct value in the combobox, and changes
get passed back to the database, BUT, the binding somehow causes EVERY
record you look at to be marked as "Modified" regardless of if you touch the
database or not!

So I thought I would create a new class that inherits from ComboBox and give
it an extra property that I could bind to. That way I would be able to
control when and if it gets changed so I tried this:

public class DataComboBox : ComboBox

{

private object bound;

public object Bound

{

get { return bound; }

set

{

if (value.ToString() != bound.ToString())

{

bound = value;

if (this.Items.Contains(bound))

{

this.Text = bound.ToString();

}

else

{

this.Text = "Unknown";

}

//this.OnTextChanged(new EventArgs());

}

}

}

public DataComboBox()

{

//

// TODO: Add constructor logic here

//

bound = this.Name;

}



protected override void OnSelectedIndexChanged(EventArgs e)

{

Bound = this.Items[this.SelectedIndex];

base.OnSelectedIndexChanged (e);

}



and bound to it like this:



MyComboBox.DataBindings.Add(new Binding("Bound",MyDataView,"MyField");



But this still has the same problem as "SelectedItem".

Can anyone please help me out here! I'm getting desperate!!



Cheers



Matt
 
Thanks for the reply. My combobox does not contain a set of objects. It
simply contains strings that are set at design time, they are not filled
from the database. Binding to the text value doesn't work, if I change the
value in the combobox then move to another record and then come back again
the original value has replaced my changed value.


Mark Boulter said:
If your combobox contains a set of objects you need to set ValueMember and
bind to selected value:

comboBox1.Items.Add(aState);
comboBox1.ValueMember = "ShortName";
comboBox1.DisplayMember = "LongName";

If you are just bound to a string value simply use Text:

sqlDataAdapter1.Fill(this.customerDataSet1);

foreach(CustomerDataSet.CustomersRow r in
customerDataSet1.Customers) {
comboBox1.Items.Add(r.Region);
}

this.textBox1.DataBindings.Add(new
System.Windows.Forms.Binding("Text", this.customerDataSet1,
"Customers.CustomerID"));
this.textBox2.DataBindings.Add(new
System.Windows.Forms.Binding("Text", this.customerDataSet1,
"Customers.ContactName"));
this.comboBox1.DataBindings.Add(new
System.Windows.Forms.Binding("Text", this.customerDataSet1,
"Customers.Region"));

mark


Matt Burland said:
Okay, I'm having MAJOR problems with this thing. Here's what I'm trying to
do: I have a form which displays information from a database and allows the
user to change it. It contains various controls such as text boxes and
comboboxes. Now, I want to use the comboboxes to restrict the user to
entering only a handful of values into certain fields so I populate the
comboboxes with the allowed values in design mode (e.g. "A","B","C") and
then bind the data source to the combobox. What should happen is that the
string from the database is matched to a value in the ComboBox.Items
collection and that item is displayed in the combobox. When the user changes
the combobox, that value should be passed back to the data source. What
I
am
NOT doing (and what 95% of databinding with combobox examples seem to
do)
is
populate a combobox with values from a database.
So I've tried:

MyComboBox.DataBindings.Add(new Binding("Text",MyDataView,"MyField");

That manages to match up the string from MyField with a value in the
combobox. The problem is that the value will not be passed back to the
database if the user changes it.

So I tried:

MyComboBox.DataBindings.Add(new
Binding("SelectedItem",MyDataView,"MyField");

This does match the string to the correct value in the combobox, and changes
get passed back to the database, BUT, the binding somehow causes EVERY
record you look at to be marked as "Modified" regardless of if you touch the
database or not!

So I thought I would create a new class that inherits from ComboBox and give
it an extra property that I could bind to. That way I would be able to
control when and if it gets changed so I tried this:

public class DataComboBox : ComboBox

{

private object bound;

public object Bound

{

get { return bound; }

set

{

if (value.ToString() != bound.ToString())

{

bound = value;

if (this.Items.Contains(bound))

{

this.Text = bound.ToString();

}

else

{

this.Text = "Unknown";

}

//this.OnTextChanged(new EventArgs());

}

}

}

public DataComboBox()

{

//

// TODO: Add constructor logic here

//

bound = this.Name;

}



protected override void OnSelectedIndexChanged(EventArgs e)

{

Bound = this.Items[this.SelectedIndex];

base.OnSelectedIndexChanged (e);

}



and bound to it like this:



MyComboBox.DataBindings.Add(new Binding("Bound",MyDataView,"MyField");



But this still has the same problem as "SelectedItem".

Can anyone please help me out here! I'm getting desperate!!



Cheers



Matt
 
Back
Top