Is it possible to do the following in a DataGridView:
In the same column I want to change the control type of each row between DataGridViewTextBoxColumn and DataGrid
You could create a template column with both controls in, hide the one you don't want, and bind the other to the datasource in code.
I've recently had a similar usecase, and ended up writing something like the below code:
Write a custom Cell and Column class, and override the EditType and InitializeEditingControl methods on the cell, to return different controls as appropriate (here I'm just databinding to a list of a custom class with .useCombo field indicating what control to use):
// Define a column that will create an appropriate type of edit control as needed.
public class OptionalDropdownColumn : DataGridViewColumn
{
public OptionalDropdownColumn()
: base(new PropertyCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a PropertyCell.
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(PropertyCell)))
{
throw new InvalidCastException("Must be a PropertyCell");
}
base.CellTemplate = value;
}
}
}
// And the corresponding Cell type
public class OptionalDropdownCell : DataGridViewTextBoxCell
{
public OptionalDropdownCell()
: base()
{
}
public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
DataItem dataItem = (DataItem) this.OwningRow.DataBoundItem;
if (dataItem.useCombo)
{
DataGridViewComboBoxEditingControl ctl = (DataGridViewComboBoxEditingControl)DataGridView.EditingControl;
ctl.DataSource = dataItem.allowedItems;
ctl.DropDownStyle = ComboBoxStyle.DropDownList;
}
else
{
DataGridViewTextBoxEditingControl ctl = (DataGridViewTextBoxEditingControl)DataGridView.EditingControl;
ctl.Text = this.Value.ToString();
}
}
public override Type EditType
{
get
{
DataItem dataItem = (DataItem)this.OwningRow.DataBoundItem;
if (dataItem.useCombo)
{
return typeof(DataGridViewComboBoxEditingControl);
}
else
{
return typeof(DataGridViewTextBoxEditingControl);
}
}
}
}
Then just add a column to your DataGridView of this type, and the correct edit control should be used.
You could create your own class inherited from DataGridViewCell, and override the adequate virtual members (InitializeEditingControls, EditType, maybe a few others). You can then create a DataGridViewColumn with an instance of this class as the cell template