P
PeterZ
G'day,
After doing much searching and pinching bits of ideas from here there and
everywhere I came up with a fairly 'clean' solution of including a comboBox
into a dataGrid column.
You can download a fully working C# sample with the Northwind.mdb here:
www.insightgis.com.au/web/stuff/DataGridCombo.zip
The whole thing works like a charm, but I have a slight problem:
When the user navigates to the new row, fills in some data, subsequent new
rows are not displayed! Meaning you can only add just ONE record! It seems
as if the DataGrid is not detecting changes made by the ComboBox, but if you
physically type some value in through the keyboard then its's happy, it
displays a subsequent new row.
Any ideas what might be causing that?
Here's the code if you don't feel like downloading the ZIP:
(Note, dataAdapers and dataGridColumnStyles have have been configured
through the IDE so you'll need the full source code to make this work)
--------------------------------------------------------------
private void Form1_Load(object sender, System.EventArgs e)
{
dbConnection.ConnectionString = @"provider=Microsoft.Jet.OLEDB.4.0; data
source=C:\NWIND.MDB";
// Load the ORDERS and CUSTOMERS tables from the Northwind demo database.
myDataSet = new DataSet();
daOrders.Fill(myDataSet, "ORDERS");
daCustomers.Fill(myDataSet, "CUSTOMERS");
myDataGrid.DataSource = myDataSet.Tables["ORDERS"];
// Create the comboBox to be used by the 'Customer Name' column in the
grid.
comboCustomers = new ComboBox();
comboCustomers.SelectionChangeCommitted += new
EventHandler(comboCustomers_SelectionChangeCommitted);
comboCustomers.Top = -4; // position the combo so that it's text is
aligned with the cell's text.
comboCustomers.Left = -4;
comboCustomers.DropDownWidth = 150;
comboCustomers.Cursor = Cursors.Arrow;
comboCustomers.DropDownStyle = ComboBoxStyle.DropDownList;
// Set the datasource for the comboBox
comboCustomers.DataSource = myDataSet.Tables["CUSTOMERS"];
comboCustomers.DisplayMember = "CompanyName";
comboCustomers.ValueMember = "CustomerId";
// Databind the combBox to the ORDERS table.
comboCustomers.DataBindings.Add("SelectedValue",
myDataSet.Tables["ORDERS"], "CustomerId");
// Assign the new comboBox to the dataGrid column.
// ... NOTE, I've defined dataGrid column styles through the IDE.
colCustomer.TextBox.Controls.Add(comboCustomers);
// Assign event handler when the user enters the 'Customer Name' cell.
colCustomer.TextBox.Enter += new EventHandler(colCustomer_Enter);
}
private void comboCustomers_SelectionChangeCommitted(object sender,
EventArgs e)
{
// Set the text in the 'Customer Name' datagrid cell (underneath the
comboBox).
myDataGrid[myDataGrid.CurrentCell] = comboCustomers.Text;
}
private void colCustomer_Enter(object sender, EventArgs e)
{
// This event handler is triggered when the user clicks on the 'Customer
Name' cell
// The purpose here is to simply display the comboBox.
if (myDataGrid.ReadOnly)
{
// Don't display the comboBox if dataGrid is readOnly!
comboCustomers.Visible = false;
return;
}
comboCustomers.Width = colCustomer.Width + 3;
comboCustomers.Visible = true;
comboCustomers.BringToFront();
}
After doing much searching and pinching bits of ideas from here there and
everywhere I came up with a fairly 'clean' solution of including a comboBox
into a dataGrid column.
You can download a fully working C# sample with the Northwind.mdb here:
www.insightgis.com.au/web/stuff/DataGridCombo.zip
The whole thing works like a charm, but I have a slight problem:
When the user navigates to the new row, fills in some data, subsequent new
rows are not displayed! Meaning you can only add just ONE record! It seems
as if the DataGrid is not detecting changes made by the ComboBox, but if you
physically type some value in through the keyboard then its's happy, it
displays a subsequent new row.
Any ideas what might be causing that?
Here's the code if you don't feel like downloading the ZIP:
(Note, dataAdapers and dataGridColumnStyles have have been configured
through the IDE so you'll need the full source code to make this work)
--------------------------------------------------------------
private void Form1_Load(object sender, System.EventArgs e)
{
dbConnection.ConnectionString = @"provider=Microsoft.Jet.OLEDB.4.0; data
source=C:\NWIND.MDB";
// Load the ORDERS and CUSTOMERS tables from the Northwind demo database.
myDataSet = new DataSet();
daOrders.Fill(myDataSet, "ORDERS");
daCustomers.Fill(myDataSet, "CUSTOMERS");
myDataGrid.DataSource = myDataSet.Tables["ORDERS"];
// Create the comboBox to be used by the 'Customer Name' column in the
grid.
comboCustomers = new ComboBox();
comboCustomers.SelectionChangeCommitted += new
EventHandler(comboCustomers_SelectionChangeCommitted);
comboCustomers.Top = -4; // position the combo so that it's text is
aligned with the cell's text.
comboCustomers.Left = -4;
comboCustomers.DropDownWidth = 150;
comboCustomers.Cursor = Cursors.Arrow;
comboCustomers.DropDownStyle = ComboBoxStyle.DropDownList;
// Set the datasource for the comboBox
comboCustomers.DataSource = myDataSet.Tables["CUSTOMERS"];
comboCustomers.DisplayMember = "CompanyName";
comboCustomers.ValueMember = "CustomerId";
// Databind the combBox to the ORDERS table.
comboCustomers.DataBindings.Add("SelectedValue",
myDataSet.Tables["ORDERS"], "CustomerId");
// Assign the new comboBox to the dataGrid column.
// ... NOTE, I've defined dataGrid column styles through the IDE.
colCustomer.TextBox.Controls.Add(comboCustomers);
// Assign event handler when the user enters the 'Customer Name' cell.
colCustomer.TextBox.Enter += new EventHandler(colCustomer_Enter);
}
private void comboCustomers_SelectionChangeCommitted(object sender,
EventArgs e)
{
// Set the text in the 'Customer Name' datagrid cell (underneath the
comboBox).
myDataGrid[myDataGrid.CurrentCell] = comboCustomers.Text;
}
private void colCustomer_Enter(object sender, EventArgs e)
{
// This event handler is triggered when the user clicks on the 'Customer
Name' cell
// The purpose here is to simply display the comboBox.
if (myDataGrid.ReadOnly)
{
// Don't display the comboBox if dataGrid is readOnly!
comboCustomers.Visible = false;
return;
}
comboCustomers.Width = colCustomer.Width + 3;
comboCustomers.Visible = true;
comboCustomers.BringToFront();
}