在 DataGridViewColumn 中混合单元格类型

问题描述 投票:0回答:2

是否可以在单个 DataGridViewColumn 中同时拥有 DataGridViewComboBoxCells 和 DataGridViewTextBoxCells?或者我绝对限制为每列只有一种类型?

.net winforms datagridview datagridviewcolumn
2个回答
9
投票

对此有一个奇怪的解决方案。
默认情况下将列创建为文本框。
处理单元格单击或单元格输入事件。
如果 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。


0
投票

当我交换单元格时,我的代码抛出以下错误

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];
           }
       }
© www.soinside.com 2019 - 2024. All rights reserved.