是否可以在单个 DataGridViewColumn 中同时拥有 DataGridViewComboBoxCells 和 DataGridViewTextBoxCells?或者我绝对限制为每列只有一种类型?
对此有一个奇怪的解决方案。
默认情况下将列创建为文本框。
处理单元格单击或单元格输入事件。
如果 ColumnIndex 匹配,则将列类型转换为 ComboBox 并设置项目。
一旦单元格离开事件从相应的列索引触发,将其转换回文本框。
在转换之前不要忘记从 Combo 中读取文本并将其设置为 TextBox。
我知道这不是合适的解决方案,但可行。
我很想知道是否有人有更好的主意。
提问者的编辑:
这是我最终编写的代码:
// 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;
}
}
此外,在创建列时,我必须确保它是通用列;即不是 DataGridViewTextBoxColumn:
var col = new DataGridViewColumn
{
CellTemplate = new DataGridViewTextBoxCell()
};
这样,我就可以稍后更改 CellTemplate。
当我交换单元格时,我的代码抛出以下错误
dataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] = cell;
System.Windows.Forms.dll 中未处理的“System.InvalidOperationException”类型异常
尽量避免在CellEnter和CellExit事件中发生上述单元格交换。 相反,我使用 DataGridView.SelectionChanged 事件来处理单元格退出和单元格输入。
if (lastDGVCellInEdit != null)
{
object value = lastDGVCellInEdit.Value;
DGV.Columns[lastDGVCellInEdit.ColumnIndex].CellTemplate = new DataGridViewTextBoxCell();
var newCell = new DataGridViewTextBoxCell { Value = value };
DGV.Rows[lastDGVCellInEdit.RowIndex].Cells[lastDGVCellInEdit.ColumnIndex] = newCell;
lastDGVCellInEdit = null;
}
if (DGV.SelectedCells.Count == 1)
{
DataGridViewCell sCell = DGV.SelectedCells[0];
int rowIndex = sCell.RowIndex;
int columnIndex = sCell.ColumnIndex;
//ComboItems are stored in Tag of DataGridViewRow
if (DGV.Rows[sCell.RowIndex].Tag != null)
{
var comboItems = DGV.Rows[sCell.RowIndex].Tag as string[];
DGV.Columns[sCell.ColumnIndex].CellTemplate = new DataGridViewComboBoxCell();
var newCell = new DataGridViewComboBoxCell { Value = sCell.Value };
newCell.Items.AddRange(comboItems);
DGV.Rows[sCell.RowIndex].Cells[sCell.ColumnIndex] = newCell;
lastDGVCellInEdit= DGV.Rows[rowIndex].Cells[columnIndex];
}
}