all groups > dotnet windows forms databinding > july 2004 >
You're in the

dotnet windows forms databinding

group:

Data bound list box displays empty item after adding new row to bound table


Data bound list box displays empty item after adding new row to bound table Torgeir Strand Henriksen
7/18/2004 1:41:21 PM
dotnet windows forms databinding:
Hi!

I have a DataSet with three tables - order, item, and one to link them
for a many-many relation. In the form, there's a combo box for selecting
the order, and a list box for displaying the items in that order.
Everything is good so far, until I add a row for the order displayed by
the combo box to the link table. An item is added to the list box, but
it has no text before switching to another order and back again. Is
there something I have forgotten to do? My code is included below.

Best regards,
Torgeir

using System;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

public class AdoTest : Form {
DataSet _data = new DataSet();

AdoTest() {
DataTable order = _data.Tables.Add("order");
DataColumn order_id = order.Columns.Add("id", typeof (int));
// add more fields later, for example customer foreign key
order.PrimaryKey = new DataColumn[] { order_id };

DataTable item = _data.Tables.Add("item");
DataColumn item_id = item.Columns.Add("id", typeof (int));
item.Columns.Add("description", typeof (string));
item.PrimaryKey = new DataColumn[] { item_id };

DataTable link = _data.Tables.Add("link");
DataColumn link_order = link.Columns.Add("order", typeof (int));
DataColumn link_item = link.Columns.Add("item", typeof (int));
link.PrimaryKey = new DataColumn[] { link_order, link_item };

_data.Relations.Add("order_link", order_id, link_order);
_data.Relations.Add("item_link", item_id, link_item);
link.Columns.Add("description", typeof (string),
"Parent(item_link).description");

for (int n = 0; n < 5; ++n) {
order.Rows.Add(new object[] { n });
}
item.Rows.Add(new object[] { 0, "stuff" });
item.Rows.Add(new object[] { 1, "other stuff" });
item.Rows.Add(new object[] { 2, "more stuff" });
item.Rows.Add(new object[] { 3, "useless junk" });

link.Rows.Add(new object[] { 0, 1 });
link.Rows.Add(new object[] { 0, 3 });
link.Rows.Add(new object[] { 1, 1 });
link.Rows.Add(new object[] { 1, 2 });
link.Rows.Add(new object[] { 2, 2 });
link.Rows.Add(new object[] { 3, 2 });
link.Rows.Add(new object[] { 3, 3 });
link.Rows.Add(new object[] { 4, 1 });
link.Rows.Add(new object[] { 4, 2 });

Label order_label = new Label();
order_label.Text = "Order";
order_label.Location = new Point(8, 8);
order_label.Size = new Size(72, 16);

ComboBox order_list = new ComboBox();
order_list.DataSource = _data;
order_list.DisplayMember = "order.id";
order_list.Location = new Point(80, 8);
order_list.Size = new Size(192, 21);

Label item_label = new Label();
item_label.Text = "Items in order";
item_label.Location = new Point(8, 48);
item_label.Size = new Size(100, 16);

ListBox item_list = new ListBox();
item_list.DataSource = _data;
item_list.DisplayMember = "order.order_link.description";
item_list.Location = new Point(8, 72);
item_list.Size = new Size(272, 95);

Button test_button = new Button();
test_button.Text = "Add item to order 0";
test_button.Location = new Point(144, 176);
test_button.Size = new Size(136, 23);
test_button.Click += new EventHandler(AddItemTest);

SuspendLayout();
ClientSize = new Size(288, 206);
Controls.Add(order_label);
Controls.Add(order_list);
Controls.Add(item_label);
Controls.Add(item_list);
Controls.Add(test_button);
ResumeLayout(false);
}

static void Main() {
Application.Run(new AdoTest());
}

void AddItemTest(object sender, System.EventArgs e) {
_data.Tables["link"].Rows.Add(new object[] { 0, 0 });
}
Re: Data bound list box displays empty item after adding new row to bound table Torgeir Strand Henriksen
7/24/2004 12:28:12 AM
I suppose there's no elegant solution to this (at least one that is
well-known), but for anyone else with a similar problem, this kludge
might work around it.

After adding the row, store the list box' display member string to a
variable. Then set the display member to null, and reset it to the
contents of the variable. This forces the list box to re-read the values
from the data source, including the proper display value of the newly
added row. If the list box reference is in a member variable, the code
now looks like this:

void AddItemTest(object sender, EventArgs e) {
_data.Tables["link"].Rows.Add(new object[] { 0, 0 });

// dirty hack to force update
string display_member = _item_list.DisplayMember;
_item_list.DisplayMember = null;
_item_list.DisplayMember = display_member;
}

Best regards,
AddThis Social Bookmark Button