Inserting ComboBoxes in a DataGrid with specific items in each row

Hi,

I need to know How can I fill a DataGrid , that contains controls like ComboBox , row by row instead of using :

tableStyle.GridColumnStyles.Add(...);

Since I need to fill the comboBox control of each row with different items.

I have wrote the follwing code but the result is empty cells in the column that expected to be ComboBoxes !!.

//***************************

DataSet myDataSet = new DataSet();

//Tags Table with comboBox

DataTable tagsTableComboBox = myDataSet.Tables.Add("Tags Table with ComboBox");

DataColumn tagID_cb = tagsTableComboBox.Columns.Add("tag_id", typeof(Int32));

DataColumn tag_cb = tagsTableComboBox.Columns.Add("Tag", typeof(string));

DataColumn similars_cb = tagsTableComboBox.Columns.Add("Similars", typeof(ComboBox));

DataGridViewComboBoxColumn c = (DataGridViewComboBoxColumn)resultsDataGridView.Columns[0];

ComboBox combobox1 = new ComboBox();

for (int i = 0; i < tpp.tagsTable.Count; i++)

{

Tag x = (Tag)(tpp.tagsTable);

combobox1.DataSource = (x.similars).ToArray();

DataRow myDataRow = tagsTableComboBox.Rows.Add(i, (string)x.similars[0],combobox1);

}

CurrencyManager cm = (CurrencyManager)resultsDataGridView.BindingContext[myDataSet];

resultsDataGridView.DataSource = myDataSet;

resultsDataGridView.DataMember = "Tags Table with ComboBox";

//****************************************

Note:

I have done another attempts:

1- Using DataGridView control

1- Inserting a DataGridView control into my form

2-using DataGridView Tasks Dialog --> Add column --> DataGridViewComboBox Type ,

I have added a comboBox column to the grid.

Now I need to fill each comboBox in each Row with specific value related to that row, my problem is that all comboBoxes in all rows in that column are filled with one value.

The code snip is followed.

//*********************************************

//Tags Table with comboBox

DataTable tagsTableComboBox = myDataSet.Tables.Add("Tags Table with CpmboBox");

DataColumn tagID_cb = tagsTableComboBox.Columns.Add("tag_id", typeof(Int32));

DataColumn tag_cb = tagsTableComboBox.Columns.Add("Tag", typeof(string));

DataGridViewComboBoxColumn c = (DataGridViewComboBoxColumn)resultsDataGridView.Columns[0];

for (int i = 0; i < tpp.tagsTable.Count; i++)

{

Tag x = (Tag)(tpp.tagsTable);

c.DataSource = (x.similars).ToArray();

DataRow myDataRow = tagsTableComboBox.Rows.Add(i, (string)x.similars[0]);

}

CurrencyManager cm = (CurrencyManager)resultsDataGridView.BindingContext[myDataSet];

resultsDataGridView.DataSource = myDataSet;

resultsDataGridView.DataMember = "Tags Table with CpmboBox";

//****************************************************************

2-using the table style with DataGrid

//**************

DataGridTableStyle tableStyle = new DataGridTableStyle();

DataGridTextBoxColumn columnTextBox;

X.DataGridComboBoxColumn columnComboBox;

DataGridViewComboBoxColumn cv ;

columnTextBox = new DataGridTextBoxColumn();

columnTextBox.MappingName = tagsTableComboBox.Columns[0].ColumnName;

columnTextBox.HeaderText = tagsTableComboBox.Columns[0].Caption;

columnTextBox.Width = 80;

columnTextBox.Alignment = HorizontalAlignment.Left;

columnTextBox.ReadOnly = true;

tableStyle.GridColumnStyles.Add(columnTextBox);

columnTextBox = new DataGridTextBoxColumn();

columnTextBox.MappingName = tagsTableComboBox.Columns[1].ColumnName;

columnTextBox.HeaderText = tagsTableComboBox.Columns[1].Caption;

columnTextBox.Width = 80;

columnTextBox.Alignment = HorizontalAlignment.Right;

columnTextBox.ReadOnly = true;

tableStyle.GridColumnStyles.Add(columnTextBox);

columnComboBox = new X.DataGridComboBoxColumn();

columnComboBox.MappingName = tagsTableComboBox.Columns[2].ColumnName;

columnComboBox.HeaderText = tagsTableComboBox.Columns[2].Caption;

columnComboBox.Width = 80;

columnComboBox.Alignment = HorizontalAlignment.Right;

columnComboBox.ReadOnly = true;

tableStyle.GridColumnStyles.Add(columnComboBox);

tableStyle.MappingName = myDataSet.Tables[2].TableName;

tableStyle.AlternatingBackColor = Color.Gainsboro;

tableStyle.AllowSorting = false;

tableStyle.ReadOnly = true;

dataGrid1.TableStyles.Clear();

dataGrid1.TableStyles.Add(tableStyle);

dataGrid1.DataSource = myDataSet;

dataGrid1.DataMember = "Tags Table with ComboBox";

tableStyle.MappingName = dataGrid1.DataSource.GetType().Name;

//*************

where X namespace has the definition of the DataGridComboBoxColumn class as follows:

//----------------

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

namespace X

{

#region DataGridComboBoxColumn

//**********************************************************************************************

// DataGridComboBoxColumn

//**********************************************************************************************

public class DataGridComboBoxColumn : DataGridColumnStyle

{

private DataGridComboBox combobox;

private bool edit;

//-------------------------------------------------------------------------------------------

// Constructors and destructors

//-------------------------------------------------------------------------------------------

public DataGridComboBoxColumn()

{

combobox = new DataGridComboBox();

combobox.Visible = false;

combobox.DropDownStyle = ComboBoxStyle.DropDownList;

combobox.Leave += new EventHandler(ComboHide);

combobox.SelectionChangeCommitted += new EventHandler(ComboStartEditing);

edit = false;

} // DataGridComboBoxColumn

//-------------------------------------------------------------------------------------------

// Properties

//-------------------------------------------------------------------------------------------

public ComboBox comboBox

{

get

{

return combobox;

}

} // comboBox

//-------------------------------------------------------------------------------------------

// ComboBox event handlers

//-------------------------------------------------------------------------------------------

private void ComboHide(object sender, EventArgs e)

{

// When the ComboBox looses focus, then simply hide it.

combobox.Hide();

} // ComboHide

private void ComboStartEditing(object sender, EventArgs e)

{

// Enter edit mode.

edit = true;

base.ColumnStartedEditing((Control)sender);

} // ComboStartEditing

//-------------------------------------------------------------------------------------------

// Override DataGridColumnStyle

//-------------------------------------------------------------------------------------------

protected override void SetDataGridInColumn(DataGrid value)

{

// Add the ComboBox to the DataGrids controls collection.

// This ensures correct DataGrid scrolling.

value.Controls.Add(combobox);

base.SetDataGridInColumn(value);

} // SetDataGridInColumn

protected override void Abort(int rowNum)

{

// Abort edit mode, discard changes and hide the ComboBox.

edit = false;

Invalidate();

combobox.Hide();

} // Abort

protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)

{

// Setup the ComboBox for action.

// This includes positioning the ComboBox and showing it.

// Also select the correct item in the ComboBox before it is shown.

combobox.Parent = this.DataGridTableStyle.DataGrid;

combobox.Bounds = bounds;

combobox.Size = new Size(this.Width, this.comboBox.Height);

comboBox.SelectedValue = base.GetColumnValueAtRow(source, rowNum).ToString();

combobox.Visible = (cellIsVisible == true) && (readOnly == false);

combobox.BringToFront();

combobox.Focus();

} // Edit

protected override bool Commit(System.Windows.Forms.CurrencyManager source, int rowNum)

{

// Commit the selected value from the ComboBox to the DataGrid.

if (edit == true)

{

edit = false;

this.SetColumnValueAtRow(source, rowNum, combobox.SelectedValue);

}

return true;

} // Commit

protected override object GetColumnValueAtRow(System.Windows.Forms.CurrencyManager source, int rowNum)

{

// Return the display text associated with the data, insted of the

// data from the DataGrid datasource.

return combobox.GetDisplayText(base.GetColumnValueAtRow(source, rowNum));

} // GetColumnValueAtRow

protected override void SetColumnValueAtRow(CurrencyManager source, int rowNum, object value)

{

// Save the data (value) to the DataGrid datasource.

// I try a few different types, because I often uses GUIDs as keys in my

// data.

// String.

try

{

base.SetColumnValueAtRow(source, rowNum, value.ToString());

return;

}

catch { }

// Guid.

try

{

base.SetColumnValueAtRow(source, rowNum, new Guid(value.ToString()));

return;

}

catch { }

// Object (default).

base.SetColumnValueAtRow(source, rowNum, value);

} // SetColumnValueAtRow

protected override int GetMinimumHeight()

{

// Return the ComboBox preferred height, plus a few pixels.

return combobox.PreferredHeight + 2;

} // GetMinimumHeight

protected override int GetPreferredHeight(Graphics g, object val)

{

// Return the font height, plus a few pixels.

return FontHeight + 2;

} // GetPreferredHeight

protected override Size GetPreferredSize(Graphics g, object val)

{

// Return the preferred width.

// Iterate through all display texts in the dropdown, and measure each

// text width.

int widest = 0;

SizeF stringSize = new SizeF(0, 0);

foreach (string text in combobox.GetDisplayText())

{

stringSize = g.MeasureString(text, base.DataGridTableStyle.DataGrid.Font);

if (stringSize.Width > widest)

{

widest = (int)Math.Ceiling(stringSize.Width);

}

}

return new Size(widest + 25, combobox.PreferredHeight + 2);

} // GetPreferredSize

protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)

{

Paint(g, bounds, source, rowNum, false);

} // Paint

protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)

{

string text = GetColumnValueAtRow(source, rowNum).ToString();

Brush backBrush = new SolidBrush(base.DataGridTableStyle.BackColor);

Brush foreBrush = new SolidBrush(base.DataGridTableStyle.ForeColor);

Rectangle rect = bounds;

StringFormat format = new StringFormat();

// Handle that the row can be selected.

if (base.DataGridTableStyle.DataGrid.IsSelected(rowNum) == true)

{

backBrush = new SolidBrush(base.DataGridTableStyle.SelectionBackColor);

foreBrush = new SolidBrush(base.DataGridTableStyle.SelectionForeColor);

}

// Handle align to right.

if (alignToRight == true)

{

format.FormatFlags = StringFormatFlags.DirectionRightToLeft;

}

// Handle alignment.

switch (this.Alignment)

{

case HorizontalAlignment.Left:

format.Alignment = StringAlignment.Near;

break;

case HorizontalAlignment.Right:

format.Alignment = StringAlignment.Far;

break;

case HorizontalAlignment.Center:

format.Alignment = StringAlignment.Center;

break;

}

// Paint.

format.FormatFlags = StringFormatFlags.NoWrap;

g.FillRectangle(backBrush, rect);

rect.Offset(0, 2);

rect.Height -= 2;

g.DrawString(text, this.DataGridTableStyle.DataGrid.Font, foreBrush, rect, format);

format.Dispose();

} // PaintText

} // DataGridComboBoxColumn

#endregion

#region DataGridComboBox

//**********************************************************************************************

// DataGridComboBox

//**********************************************************************************************

public class DataGridComboBox : ComboBox

{

private const int WM_KEYUP = 0x101;

protected override void WndProc(ref System.Windows.Forms.Message message)

{

// Ignore keyup to avoid problem with tabbing and dropdown list.

if (message.Msg == WM_KEYUP)

{

return;

}

base.WndProc(ref message);

} // WndProc

public string GetValueText(int index)

{

// Validate the index.

if ((index < 0) && (index >= base.Items.Count))

throw new IndexOutOfRangeException("Invalid index.");

// Get the text.

string text = string.Empty;

int memIndex = -1;

try

{

base.BeginUpdate();

memIndex = base.SelectedIndex;

base.SelectedIndex = index;

text = base.SelectedValue.ToString();

base.SelectedIndex = memIndex;

}

catch

{

}

finally

{

base.EndUpdate();

}

return text;

} // GetValueText

public string GetDisplayText(int index)

{

// Validate the index.

if ((index < 0) && (index >= base.Items.Count))

throw new IndexOutOfRangeException("Invalid index.");

// Get the text.

string text = string.Empty;

int memIndex = -1;

try

{

base.BeginUpdate();

memIndex = base.SelectedIndex;

base.SelectedIndex = index;

text = base.SelectedItem.ToString();

base.SelectedIndex = memIndex;

}

catch

{

}

finally

{

base.EndUpdate();

}

return text;

} // GetDisplayText

public string GetDisplayText(object value)

{

// Get the text.

string text = string.Empty;

int memIndex = -1;

try

{

base.BeginUpdate();

memIndex = base.SelectedIndex;

base.SelectedValue = value.ToString();

text = base.SelectedItem.ToString();

base.SelectedIndex = memIndex;

}

catch

{

}

finally

{

base.EndUpdate();

}

return text;

} // GetDisplayText

public string[] GetDisplayText()

{

// Get the text.

string[] text = new string[base.Items.Count];

int memIndex = -1;

try

{

base.BeginUpdate();

memIndex = base.SelectedIndex;

for (int index = 0; index < base.Items.Count; index++)

{

base.SelectedIndex = index;

text[index] = base.SelectedItem.ToString();

}

base.SelectedIndex = memIndex;

}

catch

{

}

finally

{

base.EndUpdate();

}

return text;

} // GetDisplayText

} // DataGridComboBox

#endregion

}

//----------------

also the result is empty cells in the column that expected to be ComboBoxes !!.

So, How can I solve that .

Thanks in advance for any help,

Aya.



Answer this question

Inserting ComboBoxes in a DataGrid with specific items in each row