Mixing cell types in a DataGridViewColumn

2019-02-07 09:13发布

问题:

Is it possible to have both DataGridViewComboBoxCells and DataGridViewTextBoxCells in a single DataGridViewColumn? Or am I absolutely restricted to having one type per column?

回答1:

There is a weird solution for this.
By default create the column as TextBox.
Handle the cell click or cell enter event.
In the event if the ColumnIndex matches, Convert the column type to ComboBox and set the items.
Once the cell leave event fires from the respective column index, convert it back to textbox.
Dont forget to read the text from Combo before converting and set it to TextBox.

I know this is not apt solution but works.
I am eager to know if anyone has a better idea.

Questioner's EDIT:

Here was the code I ultimately wrote:

// Using CellClick and CellLeave in this way allows us
// to stick combo boxes in a particular row, even if the
// parent column type is different
private void dataGrid_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex >= FIRST_COL && e.ColumnIndex <= LAST_COL && e.RowIndex == ROW_OF_INTEREST)
    {
        object value = dataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        dataGrid.Columns[e.ColumnIndex].CellTemplate = new DataGridViewComboBoxCell();
        var cell = new DataGridViewComboBoxCell {Value = value};
        cell.Items.AddRange(_values);
        dataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] = cell;
    }
}

private void dataGrid_CellLeave(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex >= FIRST_COL && e.ColumnIndex <= LAST_COL && e.RowIndex == ROW_OF_INTEREST)
    {
        object value = dataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        dataGrid.Columns[e.ColumnIndex].CellTemplate = new DataGridViewTextBoxCell();
        var cell = new DataGridViewTextBoxCell {Value = value};
        dataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] = cell;
    }
}

Also, when creating the column, I had to make sure it was a generic column; i.e. not a DataGridViewTextBoxColumn:

var col = new DataGridViewColumn
              {
                  CellTemplate = new DataGridViewTextBoxCell()
              };

That way, I could change the CellTemplate later.