472,973 Members | 2,395 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,973 software developers and data experts.

DataGrid with ComboBox - won't allow me to add more than one new row???

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:
http://www.insightgis.com.au/web/stu...aGridCombo.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_SelectionChangeCommitt ed);
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();
}

--------------------------------------------------------------

Cheers,
PeterZ
Nov 16 '05 #1
3 2976
Haven't looked through the code, but make sure you call BeginEdit()
method, when editing starts otherwise you will only get one new row.

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

PeterZ wrote:
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:
http://www.insightgis.com.au/web/stu...aGridCombo.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_SelectionChangeCommitt ed);
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();
}

--------------------------------------------------------------

Cheers,
PeterZ

Nov 16 '05 #2
Hi Sijin,

Tried including BeginEdit() but I still don't get additional new rows.

This is the code when I commit the selection in the comboBox:
private void comboCustomers_SelectionChangeCommitted(object sender,
EventArgs e)
{
// Set the text in the 'Customer Name' datagrid cell (underneath the
comboBox).

int colNum = myDataGrid.CurrentCell.ColumnNumber;
int rowNum = myDataGrid.CurrentCell.RowNumber;

myDataGrid.BeginEdit(colCustomer, rowNum);
myDataGrid[myDataGrid.CurrentCell] = comboCustomers.Text;
myDataGrid.EndEdit(colCustomer, rowNum, false);
}
A new row doesn't appear until I physically type in a value in one of the
other columns.

"Sijin Joseph" <si***************@hotmail.com> wrote in message
news:OY**************@TK2MSFTNGP10.phx.gbl...
Haven't looked through the code, but make sure you call BeginEdit()
method, when editing starts otherwise you will only get one new row.

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

PeterZ wrote:
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:
http://www.insightgis.com.au/web/stu...aGridCombo.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_SelectionChangeCommitt ed);
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();
}

--------------------------------------------------------------

Cheers,
PeterZ

Nov 16 '05 #3
Add this code to the comboBox TextChanged event handler, where isEditing
is a bool variable that keeps track of wether the combo is editing
or not. I am also attaching a class that i wrote that creates a custom
combo box column based on the genghis autocomplete combo box control.

private void combo_TextChanged(object sender,EventArgs e)
{
if(!_isEditing)
{
_isEditing = true;
base.ColumnStartedEditing(_combo);
}
}

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

PeterZ wrote:
Hi Sijin,

Tried including BeginEdit() but I still don't get additional new rows.

This is the code when I commit the selection in the comboBox:
private void comboCustomers_SelectionChangeCommitted(object sender,
EventArgs e)
{
// Set the text in the 'Customer Name' datagrid cell (underneath the
comboBox).

int colNum = myDataGrid.CurrentCell.ColumnNumber;
int rowNum = myDataGrid.CurrentCell.RowNumber;

myDataGrid.BeginEdit(colCustomer, rowNum);
myDataGrid[myDataGrid.CurrentCell] = comboCustomers.Text;
myDataGrid.EndEdit(colCustomer, rowNum, false);
}
A new row doesn't appear until I physically type in a value in one of the
other columns.

"Sijin Joseph" <si***************@hotmail.com> wrote in message
news:OY**************@TK2MSFTNGP10.phx.gbl...
Haven't looked through the code, but make sure you call BeginEdit()
method, when editing starts otherwise you will only get one new row.

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

PeterZ wrote:
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:
http://www.insightgis.com.au/web/stu...aGridCombo.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_SelectionChangeComm itted);
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();
}

--------------------------------------------------------------

Cheers,
PeterZ



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

using Genghis.Windows.Forms;

namespace CHF.Costing.CustomColumnStyles
{
/// <summary>
///
/// </summary>
public class DataGridAutoCompleteComboColumn : DataGridColumnStyle
{
#region Fields
private bool _isEditing = false;
private DataGridCompletionCombo _combo = new DataGridCompletionCombo();
private string oldValue = null;
private const int xMargin = 1;
private const int yMargin = 2;
private DataGrid _grid = null;
#endregion

#region Ctor
public DataGridAutoCompleteComboColumn()
{
_combo.Visible = false;
}
#endregion

#region Public Methods
public void SetItems(object[] items)
{
_combo.Items.AddRange(items);
}
#endregion

#region DataGridColumnStyle Overrides
protected override void Abort(int rowNum)
{
this.EndEdit();
this.RollBack();
}

protected override bool Commit(CurrencyManager dataSource, int rowNum)
{
if (!_isEditing)
{
this.EndEdit();
return true;
}

try
{
object value = this._combo.Text;
base.SetColumnValueAtRow(dataSource, rowNum, value);
}
catch(Exception)
{
Abort(rowNum);
return false;
}
this.EndEdit();
return true;
}

protected override void Edit(CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
//If this column is readonly, then don't bother showing the combo
if(base.ReadOnly)
return;

this._combo.Text = this.GetText(base.GetColumnValueAtRow(source, rowNum));

if (cellIsVisible)
{
this._combo.Bounds = bounds;
this._combo.Visible = true;
_combo.TextChanged += new EventHandler(combo_TextChanged);
}
else
{
this._combo.Bounds = bounds;
this._combo.Visible = false;
}

this._combo.RightToLeft = base.DataGridTableStyle.DataGrid.RightToLeft;
this.oldValue = this._combo.Text;
this._combo.Focus();
this._combo.Select(0,_combo.Text.Length);

if (this._combo.Visible)
{
base.DataGridTableStyle.DataGrid.Invalidate(bounds );
}
}

protected override int GetMinimumHeight()
{
return _combo.PreferredHeight + yMargin;
}

protected override int GetPreferredHeight(System.Drawing.Graphics g, object value)
{
return _combo.PreferredHeight + yMargin;
}

protected override System.Drawing.Size GetPreferredSize(System.Drawing.Graphics g, object value)
{
return new Size(0,0);
}

protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum)
{
Paint(g,bounds,source,rowNum,false);
}

protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
{
string text = GetText(this.GetColumnValueAtRow( source, rowNum ));
Brush bgBrush = null;
Brush fgBrush = null;
if(_grid.IsSelected(rowNum))
{
bgBrush = new SolidBrush( this.DataGridTableStyle.SelectionBackColor );
fgBrush= new SolidBrush( this.DataGridTableStyle.SelectionForeColor );
}
else
{
bgBrush = new SolidBrush( this.DataGridTableStyle.BackColor );
fgBrush= new SolidBrush( this.DataGridTableStyle.ForeColor );
}

g.FillRectangle( bgBrush, bounds );
g.DrawString( text, this.DataGridTableStyle.DataGrid.Font, fgBrush, bounds );
}

protected override void SetDataGridInColumn(DataGrid value)
{
base.SetDataGridInColumn(value);
if (this._combo.Parent != null)
{
this._combo.Parent.Controls.Remove(this._combo);

}

if (value != null)
{
value.Controls.Add(this._combo);

}

_grid = value;
}

protected override void ConcedeFocus()
{
HideCombo();

}
#endregion

#region Helper Methods
protected string GetText(object value)
{
if(value == null)
return this.NullText;
else
return value.ToString();
}

protected void RollBack()
{
this._combo.Text = this.oldValue;
}

protected void HideCombo()
{
this._combo.Visible = false;
}

protected void EndEdit()
{
_combo.TextChanged -= new EventHandler(combo_TextChanged);
HideCombo();
_isEditing = false;
base.Invalidate();
}
#endregion

#region ComboBox Event Handlers
private void combo_TextChanged(object sender,EventArgs e)
{
if(!_isEditing)
{
_isEditing = true;
base.ColumnStartedEditing(_combo);
}
}
#endregion
}
}

Nov 16 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Gamze | last post by:
Hi, How can i get values from datagrid to combobox and should select the same name as in datagrid row on the combobox control In my vb.net windows application ,i have combobox which is...
1
by: anonymous | last post by:
I've been trying to put a them, please help me out. Here's the major parts of my code: public Form1() { DataSet myDataSet = new DataSet("myDataSet"); DataTable testTable = new...
3
by: Doug | last post by:
Hi I have the following code (not mine) that populates a datagrid with some file names. But I want to replace the datagrid with a combo box. private void OnCurrentDataCellChanged(object sender,...
4
by: Pacific Design Studios | last post by:
I have a DataGrid on Form1 that displays a small amount of information about employees. On Form2 I want to have all the data displaying in text boxes about the employee selected in the datagrid on...
5
by: jaYPee | last post by:
i have successfully added a combobox to my datagrid by setting their datasource from one of my table. here's my code... Dim grdColStyle6 As New DataGridComboBoxColumn() With grdColStyle6...
1
by: John Doe | last post by:
Now i know how to manually add a combobox to a datagrid, but how would i handle the recordset below? ID | FirstName | LastName | Job -------------------------------- 1 |Joe | Smith |...
6
by: Doug Bell | last post by:
Hi I have a datagrid with a combo box, I need to populate the combo with data dependant on the record value. eg for record 1, field Warehouse = 2R so combo would allow selection of locations...
1
by: Larry Woods | last post by:
I have a combobox that is populated with a list of names. When a name is selected I want to populate a datagrid with name information. I have my master-detail defined in my dataset and it works...
4
by: Jan Nielsen | last post by:
Hi all I'm a former Access developer who would like to implement a many-to-many relation in about the same way you do in Access: With a subform and a combo box. Is it possible to use a...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.