I have built a simple test program. the Program has a two column datagridview where both are comboboxes. the choices of the first column change the choices of the second comboboxes (or switches the 2nd column back to a textbox if the user doesn't need choices).
As I make changes to combobox Column1 the correct changes are made to the second column.
However, when I leave the combobox cell and go to another row. I get the following error.
An unhandled exception of type 'System.StackOverflowException' occurred in System.Drawing.dll
Can one help with the cause and correction of this error. I have done some searching but can't find anything.
To try the code all you need to do is create a new project and drag a datagridview onto the screen. In the properties of the datagrid I have EditMode set to EditOnEnter (This makes the dropdownlist drop down right away when you click on the box).
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CboAndTxt
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DataTable dt = new DataTable();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("aa");
dt.Columns.Add("bb");
for (int i = 1; i < 20; i++)
{
if (i % 2 == 0)
dt.Rows.Add("Inventory","");
else
dt.Rows.Add("Customer", "item1");
}
dt.AcceptChanges();
this.dataGridView1.DataSource = dt;
//Change First Column
this.dataGridView1.Columns.RemoveAt(0);
DataGridViewComboBoxColumn cbc0 = new DataGridViewComboBoxColumn();
cbc0.HeaderText = "aa";
cbc0.Items.AddRange(new object[] { "Inventory", "Customer", "Discard" });
cbc0.DataPropertyName = "aa";
this.dataGridView1.Columns.Add(cbc0);
//Note the above code just made a shift of column
// aa was removed
// bb went to position column0
// aa added to position column1
//Change Second Column
this.dataGridView1.Columns.RemoveAt(0); // note comments above where bb is sitting in position column0
DataGridViewComboBoxColumn cbc1 = new DataGridViewComboBoxColumn();
cbc1.HeaderText = "bb";
cbc1.Items.AddRange(new object[] { "item1", "item2", "item3" });
cbc1.DataPropertyName = "bb";
this.dataGridView1.Columns.Add(cbc1);
foreach (DataGridViewRow dr in this.dataGridView1.Rows)
{
if (dr.Cells[0].Value != null)
{
if (dr.Cells[0].Value.ToString() != "Customer")
{
DataGridViewTextBoxCell txtcell = new DataGridViewTextBoxCell();
dr.Cells[1] = txtcell;
dr.Cells[1].ReadOnly = true;
}
}
}
this.dataGridView1.EditingControlShowing +=new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
ComboBox combo = (ComboBox)e.Control;
if (combo != null && dgv.CurrentCell.ColumnIndex == 0)
{
// Remove an existing event-handler, if present, to avoid
// adding multiple handlers when the editing control is reused.
combo.SelectedIndexChanged -= new EventHandler(myComboBox_SelectedIndexChanged);
// Add the event handler.
combo.SelectedIndexChanged += new EventHandler(myComboBox_SelectedIndexChanged);
}
}
private void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox comboBox1 = (ComboBox)sender;
// Display index
//MessageBox.Show(comboBox1.SelectedIndex.ToString());
// Display value
//MessageBox.Show(comboBox1.Text);
int rowNum = dataGridView1.CurrentCell.RowIndex;
try
{
if (comboBox1.Text != "Customer")
{
DataGridViewTextBoxCell txtcell = new DataGridViewTextBoxCell();
this.dataGridView1.Rows[rowNum].Cells[1] = txtcell;
this.dataGridView1.Rows[rowNum].Cells[1].ReadOnly = true;
DataRowView drv = this.dataGridView1.Rows[rowNum].DataBoundItem as DataRowView;
if (drv != null)
drv[1] = DBNull.Value;
}
else
{
DataGridViewComboBoxCell cbocell = new DataGridViewComboBoxCell();
DataGridViewComboBoxColumn cm = this.dataGridView1.Columns[1] as DataGridViewComboBoxColumn;
cbocell.Items.AddRange(new object[] { "item1", "item2", "item3" });
this.dataGridView1.Rows[rowNum].Cells[1] = cbocell;
this.dataGridView1.Rows[rowNum].Cells[1].ReadOnly = false;
this.dataGridView1.Rows[rowNum].Cells[1].Value = "item1";
}
dataGridView1.EndEdit();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}