Vb.net - 使用dropdownstyle.dropdown readonly制作组合框项目 [英] Vb.net - make combobox items with dropdownstyle.dropdown readonly
问题描述
因为DropDownStyle.DropDownList的问题,我需要自定义组合框以使其像DropDownStyle.DropDownList一样工作,但它设置为DropDownStyle.DropDown。
一些预期要点:
- 用户无法编辑组合框上的数据
- 选择项目时,背景为组合框将变为浅蓝色,不仅仅是组合框中的文字,如DropDownStyle.DropDown。
我的.NET Framework是4.7
对不起我的英语。
我尝试了什么:
我创建了一个自定义组合框。通过覆盖onkeypress事件并使用FindStr()函数,我可以让用户无法编辑数据,但是当选择了一个项目时,只选择了组合框上的文本。
实际上具有DropDownList样式的ComboBox项是ReadOnly(不可由用户修改)。确保将DrawMode设置为Normal,否则在需要自定义ComboBox时更改它。这是我前段时间写的一个定制的ComboBox。
选项 严格 开启
公开 类 Super_ComboBox:继承 System.Windows.Forms.ComboBox
公开 Sub 新()
' Me.DoubleBuffered = True
' Me.ResizeRedraw = True
使用 _ButtonArea
.X = Me .ClientRectangle.X - 1
.Y = 我跨度> .ClientRectangle.Y - 1
.Width = Me .ClientRectangle.Width + 2
.Height = 我 .ClientRectangle.Height + 2
结束 使用
结束 Sub
#RegionFIELDS
< span class =code-keyword>私有 _ItemsForeColor 作为 新笔(Color.Black )
私有 _borderColor 作为 新笔( Me .BackColor)
私有 _pickerColor 作为 新笔(Color.Green)
私有 _displayTextProperty As 布尔 = 错误
私有 _displayText As 字符串
私有 _ItemsBackColor As SolidBrush = 新 SolidBrush(Color.FromKnownColor(KnownColor.ControlLight))
Private _ItemsFont As Font = 新字体( Calibri Light, 10 ,FontStyle.Regular)
私有 _DropDownSign 作为 布尔 = True
#End Region
#RegionPROPERTIES
''' < 摘要 >
''' 获取或设置下拉项目的前景色。
''' < / summary >
''' < 返回 < span class =code-summarycomment>> < / returns >
公开 属性 ItemsForeColor As 颜色
获取
返回 _ItemsForeColor.Color
结束 获取
设置(值 As 颜色)
_ItemsForeColor.Color = value
我 .Invalidate()
结束 设置
< span class =code-keyword>结束 属性
''' < 摘要 >
''' 获取或设置Combobox的Bordercolor 。
''' < / summary >
''' < 返回 < span class =code-summarycomment>> < / returns >
公开 属性 BorderColor As 颜色
获取
返回 _borderColor.Color
结束 获取
设置(值作为颜色)
_borderColor.Color = value
我 .Invalidate()
结束 设置
结束 属性
''' < 摘要 > ;
''' 获取或设置所选下拉项目的背景颜色。
''' < / summary >
''' < 返回 < span class =code-summarycomment>> < / returns >
公开 属性 PickerColor As 颜色
获取
返回 _pickerColor.Color
结束 获取
设置(值作为颜色)
_pickerColor.Color = value
我 .Invalidate()
结束 设置
结束 属性
公共 属性 DisplayTextProperty 作为 布尔
获取
返回 _displayTextProperty
结束 获取
设置(值 As 布尔)
_displayTextProperty = value
我 .Refresh()
结束 设置
结束 属性
公共 属性 DisplayText 作为 字符串
获取
返回 _displayText
结束 获取
设置(值为 String )
_displayText = value
Me .Invalidate()
结束 设置
结束 属性
公共 属性 ItemsBackColor As 颜色
获取
返回 _ItemsBackColor.Color
结束 获取
设置( value As Color)
_ItemsBackColor.Color = value
End 设置
结束 属性
< span class =code-summarycomment>''' < 摘要 >
''' 获取或设置下拉项的字体。
''' < / summary >
''' < 返回 < span class =code-summarycomment>> < / returns >
公开 属性 ItemsFont As 字体
获取
返回 _ItemsFont
结束 获取
设置(value As 字体)
_ItemsFont = value
Me .Invalidate( )
结束 设置
结束 属性
公共 属性 DropDownSign 作为 布尔
获取
返回 _DropDownSign
结束 获取
设置(值作为 Boolean )
_DropDownSign = value
Me .Invalidate()
结束 设置
结束 属性
#End Region
私人 Sub SetCustomStyles()
Me .SetStyle(ControlStyles.AllPaintingInWmPaint < span class =code-keyword>或 ControlStyles.UserPaint 或 ControlStyles.SupportsTransparentBackColor 或 ControlStyles.ResizeRedraw, True )
我 .UpdateStyles()
结束 Sub
私有 Sub SetDefaultStyles()
Me .SetStyle(ControlStyles.AllP aintingInWmPaint 或 ControlStyles.UserPaint 或 ControlStyles.SupportsTransparentBackColor, False )
我 .UpdateStyles()
结束 Sub
公开 重载 属性 DrawMode 作为 DrawMode
获取
返回 MyBase .DrawMode
结束 获取
设置(值 As DrawMode)
MyBase .DrawMode = value
选择 案例值
案例 Windows.Forms.DrawMode .Normal
SetDefaultStyles()
Case Windows.Forms.DrawMode.OwnerDrawFixed,Windows.Forms.DrawMode.OwnerDrawVariable
SetCustomStyles()
结束 选择
结束 设置
结束 属性
私有 Sub Me_DrawItem(sender 作为 对象,e 作为 DrawItemEventArgs)句柄 我 .DrawIt em
如果( Me .Items.Count = 0 )然后 返回
如果(不 e.Index =( - 1))那么
e.DrawBackground()
e.Graphics.FillRectangle(_ItemsBackColor,e.Bounds)
If ((e.State < span class =code-keyword>和 DrawItemState.Selected)= DrawItemState.Selected)然后
' 活动项目
e.Graphics.FillRectangle(_pickerColor.Brush,e.Bounds)
Else
' 非活动项目
结束 如果
Dim txt 作为 字符串 = 我 .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 如果
结束 Sub
私有 _ButtonArea 作为 新矩形
私有 Sub Super_ComboBox_Paint(sender 甲s 对象,e 作为 PaintEventArgs)句柄 我 .Paint
如果(我 .DrawMode = Windows.Forms.DrawMode.Normal)然后 返回
使用 e
Dim sb 正如 Brush = 新 SolidBrush( Me .ForeColor)
如果 我 .DroppedDown 然后
ButtonRenderer。 DrawButton(e.Graphics, Me .DisplayRectangle,VisualStyles.PushButtonState.Pressed)
否则
' 在buttonrenderer上绘制背景
Dim br_backcolor As Brush = 新 SolidBrush( Me .BackColor)
e.Graphics.FillRectangle(br_backcolor,_ButtonArea)
br_backcolor.Dispose()
' 绘制边框
e.Graphics.DrawRectangle(_borderColor,新矩形( 0 , 0 ,我 .DisplayRectangle.Width - 1 , Me .DisplayRectangle.Height - 1 ))
' 绘制下拉符号
如果 DropDownSign 然后
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 作为 字符串 = 字符 .ConvertFromUtf32(& H25B2)
< span class =code-keyword> Dim triangle_down As String = 字符跨度> .ConvertFromUtf3 2(& H25BC)
Dim ft As 新字体( Arial, 7 .0!,FontStyle.Regular)
e.Graphics.DrawString(triangle_down,ft,sb, New Point(_ButtonArea.Width - 20 , CInt ((_ ButtonArea.Height - 10 )/ 2 )))
ft.Dispose()
结束 如果
结束 如果
' 绘制显示文字
Dim txt As String =
如果(DisplayTextProperty)那么
txt = 我 .DisplayText
否则
如果(不 我 .SelectedItem 是 没什么)然后 txt = 我.SelectedItem.ToString
结束 如果
< span class =code-keyword>如果(不 txt Nothing )然后
Dim txt_size As 尺寸= e.Graphics.MeasureString(txt, Me .Font).ToSize
Dim txt_loc As Point = 新点( 2 ,(_ ButtonArea) .Height - txt_size.Height) - 2 )
Me .CreateGraphics.DrawString(txt, 我 .Font,sb,txt_loc)
结束 如果
sb.Dispose()
结束 使用
结束 Sub
私人 < span class =code-keyword> Sub Super_ComboBox_SizeChanged(sender As Object ,e < span class =code-keyword> As EventArgs)句柄 我 .SizeChanged
_ButtonArea = 我 .ClientRectangle
结束 Sub
私有 Sub Super_ComboBox_BackColorChanged(sender 作为 对象,e As EventArgs)句柄 我 .BackColorChanged
我 .Invalidate()
结束 Sub
私有 Sub Super_ComboBox_SelectedIndexChanged(发件人作为 对象,e As EventArgs)句柄 我 .SelectedIndexChanged
我 .Invalidate()
结束 < span class =code-keyword> Sub
End Class 跨度>
Because the issues with DropDownStyle.DropDownList, i need customize combobox to make it working like DropDownStyle.DropDownList but it was setting as DropDownStyle.DropDown .
Some expected main points:
- User can not edit the data on the combobox
- When an item was selected, the background of the combobox will change to light blue, not only the text on the combobox like DropDownStyle.DropDown.
My .NET Framework is 4.7
Sorry about my english.
What I have tried:
I had create a customize combobox. By overriding the onkeypress event and using FindStr() function, i can make user cannot edit data but when an item was selected, just the text on combobox was selected.
Actually the ComboBox items with the DropDownList style are ReadOnly (not modifyable by the user). Make sure to have DrawMode set to Normal, otherwise change it if you want a customized ComboBox. Here is a customized ComboBox I wrote some time ago.
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
这篇关于Vb.net - 使用dropdownstyle.dropdown readonly制作组合框项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!