如何在DataGridViewComboBox列中绘制非活动行?

时间:2015-07-16 11:30:23

标签: c# .net winforms custom-controls datagridviewcombobox

我可以easily paint items in DataGridViewComboBox dropdown list。但我无法弄清楚 如何在同一列中绘制非活动单元格

Example of DataGridViewComboBox

我已经看过,研究并尝试了经典ComboBox的大量例子,但我不理解DataGridViewComboBox的所有方面。

目前我有 DataGridViewCustomPaintComboBox 类派生自 DataGridViewComboBox 。供应的最低覆盖范围是多少?你能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

在没有焦点的情况下绘制非活动单元格所需的最小似乎是CellTemplate赋值和Paint()覆盖:

public class DataGridViewCustomPaintComboBox : DataGridViewComboBoxColumn
{

    public DataGridViewCustomPaintComboBox()
    {
        base.New();
        CellTemplate = new DataGridViewCustomPaintComboBoxCell();
    }

}

public class DataGridViewCustomPaintComboBoxCell : DataGridViewComboBoxCell
{

    protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
    {
        // modify received arguments here
        base.Paint(...); // paint default parts (see paintParts argument)
        // add any custom painting here

    }

}

答案 1 :(得分:2)

<强>更新

自定义绘制DataGridViewComboBox有点牵扯。实际上,它由四种不同的绘图案例组成:

对于未聚焦的单元格,您需要对CellPainting事件进行编码:

private void dataGridView1_CellPainting(object sender, 
                                        DataGridViewCellPaintingEventArgs e)
{
   // drawstuff nr 1: draw the unfocused cell
}

当单元格具有焦点时,将创建并显示实际的DataGridViewComboBoxEditingControl(它是ComboBox的直接后代)。

您需要获取它的句柄(在EditingControlShowing事件中),然后应在其DrawItem事件中编写另外三个案例:

void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0)
    {
       // drawstuff 2: draw the undropped top portion
    }
    else
    {
       if ((e.State & DrawItemState.Selected) != DrawItemState.None
       {
          // drawstuff 3:  draw a selected item
       }
       else
       {
          // drawstuff 4:  draw an unselected item   
       }
    }
 }

关于各种油漆代码的一些注释:

  • drawstuff 1:这里你应该在绘制文本后画一个箭头。为此,最好使用ComboBoxRenderer.DrawDropDownButton方法。您需要知道位置和大小,SystemInformation.VerticalScrollBarWidth应该有帮助。请注意,TextRenderer.DrawText不仅可以让您使用漂亮的TextFormatFlags来帮助对齐,还可以使用Backcolor 1}} <!/ p>

  • drawstuff 2:请注意,ComboBox遗憾地没有拾取其单元格的BackColor。它仍然有助于设置它,因此您可以将其称为目标颜色。与以下darw代码一样,您将使用e.Graphics.DrawXxx次调用和TextRenderer.DrawText的组合。为了便于参考它所属的DGV单元格,在CurrentCell事件中设置时,您可能希望将ComboBox存储在引用Tag的{​​{1}}中。< / p>

  • drawstuff 3:所选项目可能具有字体和背景的特殊颜色

  • drawstuff 4:常规项目就是:相当规律......

以下代码是我的答案的原始版本,仅涵盖案例3和4:

这是一个简短的示例,向您展示如何绘制EditingControlShowing。请注意,我只显示最低限度,并没有进入绘制彩色方块..:

我们首先定义对单元格的类级别引用:

DataGridViewComboBox

在我们设置引用的ComboBox theBoxCell = null; 中,添加一个事件处理程序并将其设置为所有者绘制模式:

EditingControlShowing

最后我们添加绘图代码:

private void dataGridView1_EditingControlShowing(object sender,
             DataGridViewEditingControlShowingEventArgs e)
{
    theBoxCell = (ComboBox) e.Control;
    theBoxCell.DrawItem += theBoxCell_DrawItem;
    theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}

我们可以将linq中的绘图代码添加到事件连接中..

结果如下:

enter image description here