Imagine you have the following two classes:
public class Parent {
private int id;
private string name;
public Parent( int id, string name ) {
this.id = id;
this.name = name;
}
public int Id {
get { return this.id; }
}
public string Name {
get { return this.name; }
}
}
public class Child : Parent {
private int parentId;
public Child( int id, int parentId, string name )
: base( id, name ) {
this.parentId = parentId;
}
public int ParentId {
get { return this.parentId; }
}
}
In the first ComboBoxColumn you display a list of possible Parents. In the second ComboBoxColumn you display Children, but only those that belong to the Chosen Parent. Here is how it goes:
public partial class Form1 : Form {
private Object selectedValue;
public Form1() {
InitializeComponent();
// Add a couple of Parents
for ( int i = 0; i < 3; ++i ) {
Parent parent = new Parent( i, String.Format( "Parent{0:00}", i ) );
this.Column1.Items.Add( parent );
// Add a couple of Children to each parent
for ( int j = 0; j < 5; ++j ) {
Child child = new Child( j, i, String.Format( "Child{0:00}", i * 10 + j ) );
this.Column2.Items.Add( child );
}
}
this.Column1.DisplayMember = "Name";
this.Column2.DisplayMember = "Name";
}
private void dataGridView1_CellParsing( object sender, DataGridViewCellParsingEventArgs e ) {
e.Value = this.selectedValue;
e.ParsingApplied = true;
}
private void dataGridView1_EditingControlShowing( object sender, DataGridViewEditingControlShowingEventArgs e ) {
ComboBox cb = e.Control as ComboBox;
if ( cb != null ) {
// remove all the children that do not belong to the choosen parent
int currentColumnIndex = this.dataGridView1.CurrentCell.ColumnIndex;
if ( currentColumnIndex == 1 ) {
cb.Items.Clear();
int currentRowIndex = this.dataGridView1.CurrentCell.RowIndex;
Object currentCellValue = this.dataGridView1.Rows[currentRowIndex].Cells[0].Value;
if ( currentCellValue != null ) {
int parentId = ( (Parent)currentCellValue ).Id;
foreach ( Child child in this.Column2.Items ) {
if ( child.ParentId == parentId ) {
cb.Items.Add( child );
}
}
}
}
cb.SelectedIndexChanged -= cb_SelectedIndexChanged;
cb.SelectedIndexChanged += cb_SelectedIndexChanged;
}
void cb_SelectedIndexChanged(object sender, EventArgs e) {
ComboBox comboBox = sender as ComboBox;
this.selectedValue = comboBox.SelectedItem;
}
}
works good, very unique approach! never realized you could have items in the cell that were different from the combobox.
in the Form constructor add
this.Column1.ValueMember = “Id”;
and in
private void dataGridView1_EditingControlShowing
replace
int parentId = ( (Parent)currentCellValue ).Id;
with
int parentId = (int)currentCellValue;
Hi Tim,
It is very good code, but it is not working when tried it with my classes. It shows error like Formatting/Displaying. Why?
Could you please help me.
hi
how use this code in vb.net with dataset
please help me
Very nice solution.
What if the requirement is to populate automatically parent based on child selection. i.e by selecting any Child element from the combobox list it should automatically select the Parent. How this should be accomplished?
Thanks