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

时间:2016-03-16 18:40:08

标签: vb.net datagridview datagridviewcombobox

在以下示例中,如何在下拉列表中突出显示(更改背景颜色)特定项目?具体来说,我在谈论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

1 个答案:

答案 0 :(得分: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 方法中。< / em>的)

在单元格值更改时设置颜色:

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