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.

Inserting ComboBoxes in a DataGrid with specific items in each row
DamonPeng
Thanks for your reply, I am already saw it.
But it does not solve my problem since the ComboBox uses a DataSource and displays it in all rows( fixed value).
I need to fill the ComboBox with different values in each row.
Thanks,
Aya.
VivMeng
Thanks everybody,
I have found the solution in the article on:
http://www.thecodeproject.com/books/PresentDataDataGridView.asp
ShopDude
Please see this article:
http://www.codeproject.com/cs/miscctrl/RenDataGridComboBoxColumn.asp
Cheers
Smitha