Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

10 Sep 2006

Using DataGridViewComboBoxColumn with Custom Objects

Earlier today i was playing with the DataGridView control. I wanted to have a couple of DataGridViewComboBoxColumns in order to limit the available input options for the user. The documentation clearly mentions the following

The DataGridViewComboBoxColumn will only work properly if there is a mapping between all its cell values that are populated by the DataGridView.DataSource property and the range of choices populated either by the DataSource property or the Items property. If this mapping doesn't exist, the message "An Error happened Formatting, Display" will appear when the column is in view.

Here is sample of a custom object

public class Slot {
	private int id;
	private DateTime dateTime;

	public Slot( int id, DateTime dateTime ) {
		this.id = id;
		this.dateTime = dateTime;
	}

	public int Id {
		get { return this.id; }
	}

	public DateTime DateTime {
		get { return this.dateTime; }
	}
}

And here is the workaround for a one to one mapping

public partial class Form1 : Form 
{
	// here we'll store the value the user selected in one of the comboboxcolumns
	private Object selectedValue;

	public Form1() 
	{
		InitializeComponent();
		selectedValues = new Object[this.dataGridView1.Columns.Count];

		// create a couple of slots an add them to the comboboxcolumns
		for ( int i = 0; i < 10; ++i ) 
		{ 
			Slot slot = new Slot( i, DateTime.Now.AddDays( i ) ); 
			this.Column1.Items.Add( slot ); 
			this.Column2.Items.Add( slot ); 
		} 
		this.Column1.DisplayMember = "DateTime"; 
		this.Column2.DisplayMember = "Id"; 
	} 
	
	private void dataGridView1_CellParsing( object sender, DataGridViewCellParsingEventArgs e ) 
	{ 
		// lookup the selected value 
		e.Value = this.selectedValue; 
		e.ParsingApplied = true; 
	} 
	
	private void dataGridView1_EditingControlShowing( object sender, DataGridViewEditingControlShowingEventArgs e ) 
	{ 
		ComboBox cb = e.Control as ComboBox; 
		if ( cb != null ) 
		{ 
			cb.SelectedIndexChanged -= cb_SelectedIndexChanged; 
			cb.SelectedIndexChanged += cb_SelectedIndexChanged; 
		} 
	} 
	
	void cb_SelectedIndexChanged(object sender, EventArgs e) 
	{ 
		ComboBox comboBox = sender as ComboBox; 
		this.selectedValue = comboBox.SelectedItem; 
	} 
}