如何在OwnerDraw组合框中以默认方式恢复绘制组合框编辑区域?

时间:2013-03-26 15:45:34

标签: vb.net winforms combobox

我有一个ComboBox的派生类,并覆盖OnDrawItem以自定义绘制下拉列表项。如何创建组合框的编辑部分(下拉列表关闭时显示的部分或下拉列表打开时显示的部分)继续以默认ComboBox的工作方式绘制?有没有办法调用基础ComboBox功能来绘制编辑区域部分,还是在OwnerDraw模式下不可用?如果它不可用,如何模拟DropDownDropDownList样式的编辑区域部分的外观?

2 个答案:

答案 0 :(得分:1)

作为DrawItemEventArgs传递的e为您提供了一些工具。要复制系统在OwnerDraw模式下为您绘制的内容,您可以执行以下操作:

Public Class MyComboBox
    Inherits System.Windows.Forms.ComboBox

    Private _font As Font = New Font(FontFamily.GenericSansSerif, 9.0, _
                                                    FontStyle.Regular)

    Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs)
        e.DrawBackground()
        If e.Index = -1 Then Exit Sub
        e.Graphics.DrawString(Me.Items(e.Index).ToString, _font, _
                              System.Drawing.Brushes.Black, _
                              New RectangleF(e.Bounds.X, e.Bounds.Y, _
                              e.Bounds.Width, e.Bounds.Height))
        e.DrawFocusRectangle()
    End Sub
End Class

编辑:

如果您要更改显示项目的绘图行为与下拉区域中绘制的项目,您可以根据DroppedDown属性分支绘图代码:

 e.DrawBackground()
 If e.Index = -1 Then Exit Sub

 If Not Me.DroppedDown Then
     e.Graphics.DrawString(Me.Items(e.Index).ToString, _font, 
                           System.Drawing.Brushes.Black, _
                           New RectangleF(e.Bounds.X, e.Bounds.Y, _
                           e.Bounds.Width, e.Bounds.Height))

 Else
     ' do whatever you want - draw something else
     Dim rectangle As Rectangle = New Rectangle(2, e.Bounds.Top + 2, _
                                 e.Bounds.Height, e.Bounds.Height - 4)
        e.Graphics.FillRectangle(Brushes.Blue, rectangle)
        e.Graphics.DrawString("foo...I'm item #" & e.Index, _font, _
                              System.Drawing.Brushes.Black, _
                              New RectangleF(e.Bounds.X + rectangle.Width, _
                              e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
 End If

 e.DrawFocusRectangle()

同样,您可以根据If Me.DropDownStyle = ComboBoxStyle.DropDownList ...进行分支等。以您喜欢的方式处理每个案例。如果你想要由OS绘制的组件提供的渐变,主题元素或其他功能,那么你必须自己绘制它们。

答案 1 :(得分:0)

这个问题实际上涉及两个问题。

  1. 为了定位组合框的编辑区域中显示的数据,请使用OnDrawItem事件中事件参数的State属性,如下所示:

    Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs)
        ' Draw the background of the item.
        e.DrawBackground()
    
        ' Skip doing anything else if the item doesn't exist.
        If e.Index = -1 Then Exit Sub
    
        If (e.State And DrawItemState.ComboBoxEdit) = DrawItemState.ComboBoxEdit Then
            ' Draw the contents of the edit area of the combo box.
        Else
            ' Draw the contents of an item in the drop down list.
    
            ' Draw the focus rectangle.
            e.DrawFocusRectangle()
        End If
    End Sub
    
  2. OwnerDraw模式不会应用系统正在使用的任何视觉样式主题,例如在按钮面上显示下拉箭头,在DropDownList样式中更改编辑区域以具有按钮面等等。其中必须在OnPaint事件处理程序中手动完成。 This question意味着在.NET框架中没有使用组合框视觉样式的开箱即用方法调用,但可能有解决方法,或者您可以手动编写样式的实现。