在 DataGridViewComboBox 下拉列表中设置特定项目的颜色

Posted

技术标签:

【中文标题】在 DataGridViewComboBox 下拉列表中设置特定项目的颜色【英文标题】:Set color of specific item within a DataGridViewComboBox dropdown list 【发布时间】:2016-03-16 18:40:07 【问题描述】:

在以下示例中,如何突出显示(更改背景颜色)下拉列表中的特定项目?具体来说,我说的是DataGridViewComboBox的“下拉列表”中的项目。

我想为用户突出显示错误选择的特定项目。

请在 vb.net 中提供一个工作代码示例。

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim dt As New DataTable

    dt.Columns.Add("id", GetType(Integer))
    dt.Columns.Add("list", GetType(String))
    dt.Columns.Add("goodChoice", GetType(Boolean))

    dt.Rows.Add(10, "Lemon")
    dt.Rows.Add(20, "Apple")
    dt.Rows.Add(30, "Star Fruit", False)
    dt.Rows.Add(40, "Orange")

    Dim newColumn As New DataGridViewComboBoxColumn()
    With newColumn
        .HeaderText = "Choices"
        .Name = "Choices"
        .DataSource = dt
        .DisplayMember = "list"
        .ValueMember = "id"
    End With
    DataGridView1.Columns.Add(newColumn)
End Sub

【问题讨论】:

Please provide a working code example in vb.net. 让您首先显示一些代码,然后尝试一下,然后也许我们可以提供帮助。 【参考方案1】:

尝试处理EditingControlShowing 事件以订阅ComboBox.DrawItem 事件。在此事件处理程序中,您将获取底层 DataTable DataSource。当该项目的goodChoiceFalse 并且该项目不是焦点项目时,填充它的背景颜色。

Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    If TypeOf e.Control Is ComboBox Then
        Dim cb As ComboBox = TryCast(e.Control, ComboBox)
        cb.DrawMode = DrawMode.OwnerDrawFixed
        RemoveHandler cb.DrawItem, AddressOf DrawGridComboBoxItem
        AddHandler cb.DrawItem, AddressOf DrawGridComboBoxItem
    End If
End Sub

Private Sub DrawGridComboBoxItem(sender As Object, e As DrawItemEventArgs)
    If e.Index <> -1 Then

        e.DrawBackground()

        Dim cb As ComboBox = TryCast(sender, ComboBox)
        Dim dt As DataTable = TryCast(cb.DataSource, DataTable)

        If (e.State And DrawItemState.Focus) <> DrawItemState.Focus AndAlso cb.DroppedDown Then
            If dt.Rows(e.Index).Item("goodChoice") Then
                e.Graphics.FillRectangle(Brushes.White, e.Bounds)
            Else ' Added for follow-up question.
                e.Graphics.FillRectangle(Brushes.Red, e.Bounds)
            End If
        End If

        e.Graphics.DrawString(dt.Rows(e.Index).Item("Name"), e.Font, Brushes.Black, e.Bounds)

        e.DrawFocusRectangle()
    End If
End Sub

我的后续问题是,如果选择了红色彩色项目,如何在退出控件的编辑模式时如何使颜色粘在一起?

设置单元格本身的BackColor。 (注意:这也会改变下拉的项目,所以我们添加一个 Else 语句到 DrawGridComboBoxItem 上面的方法。

设置单元格值变化时的颜色:

Private Sub DataGridView1_ValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
    If TypeOf DataGridView1.CurrentCell Is DataGridViewComboBoxCell Then
        Dim cell As DataGridViewComboBoxCell = TryCast(DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex), DataGridViewComboBoxCell)
        Dim dt As DataTable = TryCast(cell.DataSource, DataTable)
        Dim row() As DataRow = dt.Select("ID = " & cell.Value)

        cell.Style.BackColor = If(row(0).Item("goodChoice"), SystemColors.ControlLight, Color.Red)
    End If
End Sub

然后通过手动绘制背景来使用该颜色:

Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    If e.RowIndex >= 0 And e.ColumnIndex >= 0 Then
        If TypeOf DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewComboBoxCell Then
            Dim cell As DataGridViewComboBoxCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
            Dim color As Color = If(cell.Style.ForeColor.Name = "0", Color.Black, cell.Style.ForeColor)

            Using backbrush = New SolidBrush(cell.Style.BackColor)
                Using brush = New SolidBrush(color)
                    Using format = New StringFormat()
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.Background)
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.Border)
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.ContentBackground)
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.ErrorIcon)
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.Focus)
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.SelectionBackground)

                        format.LineAlignment = StringAlignment.Center

                        Dim rect = New Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 19, e.CellBounds.Height - 3)

                        e.Graphics.FillRectangle(backbrush, rect)
                        e.Graphics.DrawString(cell.FormattedValue, e.CellStyle.Font, brush, e.CellBounds, format)
                        e.Handled = True
                    End Using
                End Using
            End Using
        End If
    End If
End Sub

【讨论】:

效果很好,当您将鼠标悬停在所选项目上时,我想出了如何为所选项目绘制白色拉绳。我的后续问题是,如果选择了红色彩色的项目,如何在退出控制的编辑模式时如何使颜色粘在一起? span> 我已对我的回答进行了编辑以解决您的后续问题。

以上是关于在 DataGridViewComboBox 下拉列表中设置特定项目的颜色的主要内容,如果未能解决你的问题,请参考以下文章

如果 datagridviewcombobox 的值不在 datagridviewcomboboxcolumn 数据源中,我该怎么办?

vb.net 为 datagridviewcombobox 中的每个项目显示工具提示文本

DataGridViewCombobox 列中的自动完成有啥奇怪的行为?

值未显示在 DataGridViewComboBox 控件上

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

在 DataGridViewComboBox 列上设置值非常慢