VB.NET:图像作为复选框状态框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14319142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
VB.NET: Image as checkbox state box
提问by Tony Bogdanov
Is it possible to use an image as the checkbox "checked" indicator square?
是否可以将图像用作复选框“已选中”指示器方块?
I know I can use a background image, but that goes behind the label aswell and also it is not possible (as far as I know) to align it.
我知道我可以使用背景图像,但这也位于标签后面,而且也无法(据我所知)对齐它。
How can I use an image instead of the square and leave the label and all other customization as they are?
如何使用图像而不是正方形并保持标签和所有其他自定义设置不变?
Thanks in advance!
提前致谢!
回答by iBener
You look like this?
你看起来像这样吗?
Dim frm As New Form
frm.Size = New Size(320, 200)
Dim iList As New ImageList
iList.Images.Add(Image.FromFile("check.png"), Color.White)
iList.Images.Add(Image.FromFile("uncheck.png"), Color.White)
Dim chk As New CheckBox
chk.Text = "Check Box With Image"
chk.AutoSize = False
chk.Size = New Size(350, 20)
chk.ImageList = iList
chk.ImageIndex = 1
chk.CheckAlign = ContentAlignment.MiddleRight
chk.ImageAlign = ContentAlignment.MiddleLeft
chk.TextImageRelation = TextImageRelation.ImageBeforeText
chk.Location = New Point(32, 32)
frm.Controls.Add(chk)
AddHandler chk.CheckStateChanged,
Sub(sender1 As Object, e1 As EventArgs)
chk.ImageIndex = IIf(chk.Checked, 0, 1)
End Sub
frm.ShowDialog()
回答by xfx
UPDATE #1: Actually, @brahm solution's below is much better than mine!
更新 #1:实际上,@brahm 下面的解决方案比我的要好得多!
UPDATE #2: Actually, it's not. Now I see how he did it: he's moving the checkbox out of sight by placing it way off the visible Form's area. Not a great solution...
更新 #2:实际上,事实并非如此。现在我看到他是如何做到的:他将复选框移到了可见Form区域之外,从而将其移出视线。不是很好的解决方案...
The ideal solution would be to subclass the CheckBoxcontrol and do your own rendering by overriding the OnPaintmethod.
理想的解决方案是将CheckBox控件子类化并通过覆盖该OnPaint方法来进行自己的渲染。
An easier, although probably messier solution, would be to place a PictureBox over the check box and control the image in the PictureBoxthrough the CheckBox's CheckedChangeevent.
更简单的,虽然可能混乱的解决方案,将放置在复选框一个PictureBox和控制的图像PictureBox通过CheckBox的CheckedChange事件。
Another option:
You could still use the CheckBoxin button mode (Appearance = Button), as you suggested, but then add a label right next to it.
Then, handle the Clickevent on the Label to toggle the Checked state of the CheckBox. Then end result should provide you exactly what you are looking for.
另一种选择:您仍然可以按照您的建议使用CheckBox按钮模式 ( Appearance = Button),然后在其旁边添加一个标签。然后,处理ClickLabel 上的事件以切换CheckBox. 然后最终结果应该为您提供您正在寻找的内容。
回答by Error404
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Windows.Forms.VisualStyles
Public Class ImageCheckBox
Public State As CheckBoxState = CheckBoxState.UncheckedNormal
Public Hot As Boolean = False
Public Pressed As Boolean = False
Public ImageDictionary As Dictionary(Of CheckBoxState, Image) = New Dictionary(Of CheckBoxState, Image)
Private Const PaddingModifier As Integer = 2
Sub New()
Me.New(New Dictionary(Of CheckBoxState, Image) From {
{CheckBoxState.CheckedDisabled, My.Resources.form_checkbox_checked},
{CheckBoxState.CheckedHot, My.Resources.form_checkbox_checked},
{CheckBoxState.CheckedNormal, My.Resources.form_checkbox_checked},
{CheckBoxState.CheckedPressed, My.Resources.form_checkbox_checked},
{CheckBoxState.UncheckedDisabled, My.Resources.form_checkbox_unchecked},
{CheckBoxState.UncheckedHot, My.Resources.form_checkbox_unchecked},
{CheckBoxState.UncheckedNormal, My.Resources.form_checkbox_unchecked},
{CheckBoxState.UncheckedPressed, My.Resources.form_checkbox_unchecked}})
End Sub
Sub New(imageDictionary As Dictionary(Of CheckBoxState, Image))
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.ImageDictionary = imageDictionary
End Sub
Sub CheckBox_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
'Return if the specific Image is not found
If Not ImageDictionary.ContainsKey(State) Then Return
'Get the Size of the CheckBox
Dim glyphSize As Size = CheckBoxRenderer.GetGlyphSize(e.Graphics, State)
'Get the Location of the CheckBox in relation to the Alignment of it
Dim glyphLocation As Point
Select Case Me.CheckAlign
Case Drawing.ContentAlignment.TopLeft
glyphLocation = New Point(Me.Padding.Left, Me.Padding.Top)
Exit Select
Case Drawing.ContentAlignment.TopCenter
glyphLocation = New Point(Me.Padding.Left + (Me.Width - glyphSize.Width) / 2, Me.Padding.Top)
Exit Select
Case Drawing.ContentAlignment.TopRight
glyphLocation = New Point(Me.Padding.Left + Me.Width - glyphSize.Width, Me.Padding.Top)
Exit Select
Case Drawing.ContentAlignment.MiddleLeft
glyphLocation = New Point(Me.Padding.Left, Me.Padding.Top + (Me.Height - glyphSize.Height) / 2)
Exit Select
Case Drawing.ContentAlignment.MiddleCenter
glyphLocation = New Point(Me.Padding.Left + (Me.Width - glyphSize.Width) / 2, Me.Padding.Top + (Me.Height - glyphSize.Height) / 2)
Exit Select
Case Drawing.ContentAlignment.MiddleRight
glyphLocation = New Point(Me.Padding.Left + Me.Width - glyphSize.Width, Me.Padding.Top + (Me.Height - glyphSize.Height) / 2)
Exit Select
Case Drawing.ContentAlignment.BottomLeft
glyphLocation = New Point(Me.Padding.Left, Me.Padding.Top + Me.Height - glyphSize.Height)
Exit Select
Case Drawing.ContentAlignment.BottomCenter
glyphLocation = New Point(Me.Padding.Left + (Me.Width - glyphSize.Width) / 2, Me.Padding.Top + Me.Height - glyphSize.Height)
Exit Select
Case Drawing.ContentAlignment.BottomRight
glyphLocation = New Point(Me.Padding.Left + Me.Width - glyphSize.Width, Me.Padding.Top + Me.Height - glyphSize.Height)
Exit Select
End Select
'Set the drawing Area
Dim glyphRectangle As Rectangle = New Rectangle(glyphLocation, glyphSize)
'Enlarge the Rectangle to completely hide default symbol
Dim clearRectangle As Rectangle = New Rectangle(glyphLocation.X - PaddingModifier,
glyphLocation.Y - PaddingModifier,
glyphSize.Width + 2 * PaddingModifier,
glyphSize.Height + 2 * PaddingModifier)
'Draw the Parent Background over the default CheckBox to clear it
CheckBoxRenderer.DrawParentBackground(e.Graphics, clearRectangle, Me)
Debug.WriteLine(State)
'Finally draw the custom CheckBox image on the position of the default one
e.Graphics.DrawImage(ImageDictionary(State), glyphRectangle)
End Sub
Sub CheckBox_MouseClick(sender As Object, e As EventArgs) Handles Me.MouseClick
Me.Checked = Not Me.Checked
End Sub
Sub CheckBox_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
Me.Pressed = True
End Sub
Sub CheckBox_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
Me.Pressed = False
End Sub
Sub CheckBox_MouseEnter(sender As Object, e As EventArgs) Handles Me.MouseEnter
Me.Hot = True
End Sub
Sub CheckBox_MouseLeave(sender As Object, e As EventArgs) Handles Me.MouseLeave
Me.Hot = False
End Sub
Public Sub updateState() Handles Me.MouseClick, Me.MouseDown, Me.MouseUp, Me.MouseEnter, Me.MouseLeave, Me.EnabledChanged
Debug.WriteLine(Me.Checked & " " & Me.Enabled & " " & Me.Hot & " " & Me.Pressed)
Me.State = CurrentState()
Me.Refresh()
Debug.WriteLine(State)
End Sub
Public Function CurrentState() As CheckBoxState
If (Me.Checked) Then
If (Not Me.Enabled) Then Return CheckBoxState.CheckedDisabled
If (Me.Pressed) Then Return CheckBoxState.CheckedPressed
If (Me.Hot) Then Return CheckBoxState.CheckedHot
Return CheckBoxState.CheckedNormal
Else
If (Not Me.Enabled) Then Return CheckBoxState.UncheckedDisabled
If (Me.Pressed) Then Return CheckBoxState.UncheckedPressed
If (Me.Hot) Then Return CheckBoxState.UncheckedHot
Return CheckBoxState.UncheckedNormal
End If
End Function
End Class

