Tan Nguyen Dang Ответов: 1

Vb.net - создавайте элементы combobox с помощью dropdownstyle.выпадающий список только для чтения


Потому что проблемы с DropDownStyle.DropDownList, мне нужно настроить combobox, чтобы он работал как DropDownStyle.DropDownList, но он был установлен как DropDownStyle.выпадающий.
Некоторые ожидаемые основные моменты:
- Пользователь не может редактировать данные в выпадающем списке
- Когда элемент был выбран, фон combobox изменится на светло-синий, а не только текст на combobox, как DropDownStyle.выпадающий.

Мой .NET Framework-это 4.7

Извините за мой английский.

Что я уже пробовал:

Я должен был создать настраиваемый combobox. Переопределяя событие onkeypress и используя функцию FindStr (), я могу сделать так, чтобы пользователь не мог редактировать данные, но когда элемент был выбран, был выбран только текст в combobox.

Richard Deeming

Какие проблемы с DropDownStyle.DropDownList?

Если вы объясните, в чем заключается реальная проблема, а не проблемы, с которыми вы сталкиваетесь, реализуя выбранное вами решение этой проблемы, кто-то может дать вам лучшее решение.

Tan Nguyen Dang

Мой проект требовал, чтобы forecolor combobox был черным, даже если он отключен. Для этого мы переопределяем WndProc. Но из-за выпадающего стиля.DropDownList, WndProc не может сделать это точно. Мое текущее решение: заменить DropDownStyle.DropDownList по DropDownStyle.Выпадающий список и настроить combobox, чтобы сделать его действовать как DropDownStyle.Выпадающий список. Может быть, это плохое решение, но я не могу найти другого.

1 Ответов

Рейтинг:
1

User 11061201

На самом деле элементы ComboBox со стилем DropDownList доступны только для чтения (не могут быть изменены пользователем). Убедитесь, что для DrawMode установлено значение Normal, в противном случае измените его, если вам нужен настроенный ComboBox. Вот настроенный ComboBox, который я написал некоторое время назад.

Option Strict On

Public Class Super_ComboBox : Inherits System.Windows.Forms.ComboBox

    Public Sub New()
        ' Me.DoubleBuffered = True
        ' Me.ResizeRedraw = True

        With _ButtonArea
            .X = Me.ClientRectangle.X - 1
            .Y = Me.ClientRectangle.Y - 1
            .Width = Me.ClientRectangle.Width + 2
            .Height = Me.ClientRectangle.Height + 2
        End With
    End Sub

#Region "FIELDS"
    Private _ItemsForeColor As New Pen(Color.Black)
    Private _borderColor As New Pen(Me.BackColor)
    Private _pickerColor As New Pen(Color.Green)
    Private _displayTextProperty As Boolean = False
    Private _displayText As String
    Private _ItemsBackColor As SolidBrush = New SolidBrush(Color.FromKnownColor(KnownColor.ControlLight))
    Private _ItemsFont As Font = New Font("Calibri Light", 10, FontStyle.Regular)
    Private _DropDownSign As Boolean = True
#End Region

#Region "PROPERTIES"
    ''' <summary>
    ''' Gets or Sets the Forecolor of the dropdown items.
    ''' </summary>
    ''' <returns></returns>
    Public Property ItemsForeColor As Color
        Get
            Return _ItemsForeColor.Color
        End Get
        Set(value As Color)
            _ItemsForeColor.Color = value
            Me.Invalidate()
        End Set
    End Property
    ''' <summary>
    '''Gets or Sets the Bordercolor of the Combobox.
    ''' </summary>
    ''' <returns></returns>
    Public Property BorderColor As Color
        Get
            Return _borderColor.Color
        End Get
        Set(value As Color)
            _borderColor.Color = value
            Me.Invalidate()
        End Set
    End Property
    ''' <summary>
    ''' Gets or Sets the Backcolor of a selected dropdown item.
    ''' </summary>
    ''' <returns></returns>
    Public Property PickerColor As Color
        Get
            Return _pickerColor.Color
        End Get
        Set(value As Color)
            _pickerColor.Color = value
            Me.Invalidate()
        End Set
    End Property
    Public Property DisplayTextProperty As Boolean
        Get
            Return _displayTextProperty
        End Get
        Set(value As Boolean)
            _displayTextProperty = value
            Me.Refresh()
        End Set
    End Property
    Public Property DisplayText As String
        Get
            Return _displayText
        End Get
        Set(value As String)
            _displayText = value
            Me.Invalidate()
        End Set
    End Property
    Public Property ItemsBackColor As Color
        Get
            Return _ItemsBackColor.Color
        End Get
        Set(value As Color)
            _ItemsBackColor.Color = value
        End Set
    End Property
    ''' <summary>
    '''Gets or Sets the Font of the dropdown items.
    ''' </summary>
    ''' <returns></returns>
    Public Property ItemsFont As Font
        Get
            Return _ItemsFont
        End Get
        Set(value As Font)
            _ItemsFont = value
            Me.Invalidate()
        End Set
    End Property
    Public Property DropDownSign As Boolean
        Get
            Return _DropDownSign
        End Get
        Set(value As Boolean)
            _DropDownSign = value
            Me.Invalidate()
        End Set
    End Property
#End Region

    Private Sub SetCustomStyles()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.SupportsTransparentBackColor Or ControlStyles.ResizeRedraw, True)
        Me.UpdateStyles()
    End Sub
    Private Sub SetDefaultStyles()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.SupportsTransparentBackColor, False)
        Me.UpdateStyles()
    End Sub
    Public Overloads Property DrawMode As DrawMode
        Get
            Return MyBase.DrawMode
        End Get
        Set(value As DrawMode)
            MyBase.DrawMode = value
            Select Case value
                Case Windows.Forms.DrawMode.Normal
                    SetDefaultStyles()
                Case Windows.Forms.DrawMode.OwnerDrawFixed, Windows.Forms.DrawMode.OwnerDrawVariable
                    SetCustomStyles()
            End Select
        End Set
    End Property

    Private Sub Me_DrawItem(sender As Object, e As DrawItemEventArgs) Handles Me.DrawItem
        If (Me.Items.Count = 0) Then Return

        If (Not e.Index = (-1)) Then
            e.DrawBackground()
            e.Graphics.FillRectangle(_ItemsBackColor, e.Bounds)
            If ((e.State And DrawItemState.Selected) = DrawItemState.Selected) Then
                'active item
                e.Graphics.FillRectangle(_pickerColor.Brush, e.Bounds)
            Else
                'inactive items
            End If

            Dim txt As String = Me.Items(e.Index).ToString
            e.Graphics.DrawString(txt, ItemsFont, _ItemsForeColor.Brush, New Point(e.Bounds.X, e.Bounds.Y))
            e.DrawFocusRectangle()
            e.Graphics.Dispose()
        End If
    End Sub

    Private _ButtonArea As New Rectangle
    Private Sub Super_ComboBox_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
        If (Me.DrawMode = Windows.Forms.DrawMode.Normal) Then Return

        Using e
            Dim sb As Brush = New SolidBrush(Me.ForeColor)
            If Me.DroppedDown Then
                ButtonRenderer.DrawButton(e.Graphics, Me.DisplayRectangle, VisualStyles.PushButtonState.Pressed)
            Else
                'draw the background over the buttonrenderer
                Dim br_backcolor As Brush = New SolidBrush(Me.BackColor)
                e.Graphics.FillRectangle(br_backcolor, _ButtonArea)
                br_backcolor.Dispose()

                'draw border 
                e.Graphics.DrawRectangle(_borderColor, New Rectangle(0, 0, Me.DisplayRectangle.Width - 1, Me.DisplayRectangle.Height - 1))

                'draw dropdown sign
                If DropDownSign Then
                    e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
                    e.Graphics.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
                    e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
                    e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
                    Dim triangle_up As String = Char.ConvertFromUtf32(&H25B2)
                    Dim triangle_down As String = Char.ConvertFromUtf32(&H25BC)
                    Dim ft As New Font("Arial", 7.0!, FontStyle.Regular)
                    e.Graphics.DrawString(triangle_down, ft, sb, New Point(_ButtonArea.Width - 20, CInt((_ButtonArea.Height - 10) / 2)))
                    ft.Dispose()
                End If
            End If

            'draw display text
            Dim txt As String = ""
            If (DisplayTextProperty) Then
                txt = Me.DisplayText
            Else
                If (Not Me.SelectedItem Is Nothing) Then txt = Me.SelectedItem.ToString
            End If

            If (Not txt Is Nothing) Then
                Dim txt_size As Size = e.Graphics.MeasureString(txt, Me.Font).ToSize
                Dim txt_loc As Point = New Point(2, (_ButtonArea.Height - txt_size.Height) - 2)
                Me.CreateGraphics.DrawString(txt, Me.Font, sb, txt_loc)
            End If
            sb.Dispose()
        End Using

    End Sub

    Private Sub Super_ComboBox_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
        _ButtonArea = Me.ClientRectangle
    End Sub

    Private Sub Super_ComboBox_BackColorChanged(sender As Object, e As EventArgs) Handles Me.BackColorChanged
        Me.Invalidate()
    End Sub

    Private Sub Super_ComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Me.SelectedIndexChanged
        Me.Invalidate()
    End Sub

End Class


Tan Nguyen Dang

Спасибо за ваш ответ.
Прочитав ваш код, я понял, что должен установить drawmode в файле конструктора, который использует этот combobox. Я не хочу этого делать.