如何更改复选框上的勾选图像

12

它包含文字、图片和复选框。

我想为复选框使用更好的图片,但找不到更改已选和未选图片的方法。

this.checkBox1.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.checkBox1.Checked = true;
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox1.Image = global::ClientExam.Properties.Resources.action32;
this.checkBox1.Location = new System.Drawing.Point(145, 140);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(273, 127);
this.checkBox1.TabIndex = 0;
this.checkBox1.Text = "checkBox1";
this.checkBox1.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage;
this.checkBox1.UseVisualStyleBackColor = true;

有人知道一个不需要我编写自己的控制器的吗?


这是一个WinForms应用程序,我知道我可以编写自己的控件或覆盖现有的控件来实现它,但我不想重新发明轮子,因为好像已经有其他人写过类似的东西了。虽然我拥有所有的DevComponents,但它们似乎也没有这样的控件,至少我不知道。请问有谁知道是否存在一个能够直接实现这个功能的组件? - f1wade
这与早些时候的一个问题有关 http://stackoverflow.com/questions/13124813/how-to-define-a-checkbox-with-image-and-a-custom-icon - f1wade
5个回答

24

对于那些不想覆盖OnPaint的人,有另一种解决方案:

  1. 添加一个ImageList控件,并使用图像填充其以反映已选/未选状态。
  2. Checkbox控件的Appearance属性设置为Button(以摆脱标准的CheckBox图标)。
  3. 将其FlatStyle属性设置为Flat(使控件看起来不像按钮)。
    注意:您可能还想检查其FlatAppearance属性组。即CheckedBackColorMouseDownBackColorMouseOverBackColor,即设置它们都为Control值。
  4. Checkbox控件的ImageList属性设置为您的ImageList控件的名称。
  5. 根据当前状态设置Checkbox控件的ImageindexImageAlign属性。
  6. 最后,最重要的是设置Checkbox控件的TextImageRelation属性(这个值不会让文本和图像重叠,除非您想让它们重叠)。即ImageBeforetext值代表常见的CheckBox图标位置。

现在唯一剩下的事情就是在状态改变时更改图像,例如:

    private void chkMyCheckBoxWithAnImage_CheckedChanged(object sender, EventArgs e)
    {
        if (chkMyCheckBoxWithAnImage.Checked)
            chkMyCheckBoxWithAnImage.ImageIndex = 1;
        else
            chkMyCheckBoxWithAnImage.ImageIndex = 0;
    }

4
我认为这应该是答案。另一个答案没有提到除图像外,你还必须处理绘制文本的问题。 - rory.ap
2
你可以在CheckedChanged事件中直接设置图像属性,而无需使用图像列表来完成完全相同的操作。 - Darryn Frost

13

如果你正在寻找Winforms中如何实现此操作的方法,简单的回答是创建一个继承自CheckBox的新复选框类,然后覆盖OnPaint方法。

以下是通过覆盖OnPaint方法创建自定义外观复选框的示例:

public class CustomCheckBox : CheckBox
{
    public CustomCheckBox()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        base.OnPaint(pevent);
        if (this.Checked)
        {
            pevent.Graphics.FillRectangle(new SolidBrush(Color.Blue), new Rectangle(0, 0, 16, 16));
        }
        else
        {
            pevent.Graphics.FillRectangle(new SolidBrush(Color.Red), new Rectangle(0, 0, 16, 16));
        }
    }
}

这很简单,但它能让你了解基本思想。


0
一个简单的例子:
覆盖复选框 OnPaint(PaintEventArgs e) 如下:
Graphics g = e.Graphics;

        base.OnPaint(e);
        //// Fill the background
        //SetControlSizes();

        // Paint the outer rounded rectangle
        g.SmoothingMode = SmoothingMode.AntiAlias;
        using (GraphicsPath outerPath = GeneralUtilities.RoundedRectangle(mLabelRect, 1, 0))
        {
            using (LinearGradientBrush outerBrush = new LinearGradientBrush(mLabelRect,
                   mGradientTop, mGradientBottom, LinearGradientMode.Vertical))
            {
                g.FillPath(outerBrush, outerPath);
            }
            using (Pen outlinePen = new Pen(mGradientTop, mRectOutlineWidth))
            {
                outlinePen.Alignment = PenAlignment.Inset;
                g.DrawPath(outlinePen, outerPath);
            }
        }

        //// Paint the gel highlight
        using (GraphicsPath innerPath = GeneralUtilities.RoundedRectangle(mHighlightRect, mRectCornerRadius, mHighlightRectOffset))
        {
            using (LinearGradientBrush innerBrush = new LinearGradientBrush(mHighlightRect,
                   Color.FromArgb(mHighlightAlphaTop, Color.White),
                   Color.FromArgb(mHighlightAlphaBottom, Color.White), LinearGradientMode.Vertical))
            {
                g.FillPath(innerBrush, innerPath);
            }
        }
        // Paint the text
        TextRenderer.DrawText(g, Text, Font, mLabelRect, Color.White, Color.Transparent,
        TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);

但是如果你想要一个好的,你必须使用wpf CheckBox ControlTemplate Example


0

我已经用另一种方式解决了这个问题,我使用背景图像并将其居中,然后在更改选中状态时更改主要图像。这看起来就像我想要的。

但是这种方法存在一个问题,如果背景图像大小不合适,则会与选中图像重叠,因此看起来不正确。

正确的解决方案如icemanind所描述的那样。


0

Custom CheckBox

完整的自定义复选框控件,支持主题

  1. Predefined styles (VS 2019 Dark and Light).

  2. Support for AutoSize property.

  3. Support for custom colors in focused, mouse enter and mouse down events.

  4. Support for custom check mark (shape and color).

  5. Public properties to customize the look the CheckBox control.

    'Copyright (c) Smart PC Utilities, Ltd.
    'All rights reserved.
    
    #Region "References"
    
    Imports System.ComponentModel
    Imports System.Drawing.Drawing2D
    
    #End Region
    
    Namespace FlatUI
    
    ''' <summary>
    ''' Flat CheckBox control
    ''' </summary>
    Public NotInheritable Class FlatCheckBox
        Inherits CheckBox
    
    #Region "Private Members"
    
        Dim _theme As UITheme = UITheme.LightBlue
    
        Private _boxNormalBackColor As Color = Color.FromArgb(243, 249, 255)
        Private _boxFocusBackColor As Color = Color.FromArgb(243, 249, 255)
        Private _boxMouseDownBackColor As Color = Color.FromArgb(51, 153, 255)
    
        Private _boxNormalBorderColor As Color = Color.FromArgb(30, 30, 30)
        Private _boxFocusBorderColor As Color = Color.FromArgb(51, 153, 255)
        Private _boxMouseDownBorderColor As Color = Color.FromArgb(51, 153, 255)
    
        Private _checkMarkNormalColor As Color = Color.FromArgb(30, 30, 30)
        Private _checkMarkFocusColor As Color = Color.FromArgb(30, 30, 30)
        Private _checkMarkMouseDownColor As Color = Color.FromArgb(243, 249, 255)
    
        Private _focusCuesColor As Color = Color.Gray
    
        Private _isMouseEnter As Boolean
        Private _isMouseDown As Boolean
    
    #End Region
    
    #Region "Constants"
    
        Const TEXT_X = 21
        Const TEXT_Y = 2
    
        Const BOX_X = 4
        Const BOX_Y = 4
    
        Const BOX_WIDTH = 12
        Const BOX_HEIGHT = 12
    
    #End Region
    
    #Region "Public Methods"
    
        Public Sub New()
    
            SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    
            BackColor = Color.FromArgb(251, 251, 251)
            ForeColor = Color.FromArgb(30, 30, 30)
            Appearance = Appearance.Button
            FlatStyle = FlatStyle.Flat
            FlatAppearance.BorderSize = 0
            DoubleBuffered = True
            UseVisualStyleBackColor = False
    
        End Sub
    
    #End Region
    
    #Region "Public Properties"
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The box backcolor in the normal state.")> <DefaultValue(GetType(Color), "243, 249, 255")>
        Public Property BoxNormalBackColor As Color
            Get
                Return _boxNormalBackColor
            End Get
            Set(value As Color)
                _boxNormalBackColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The box backcolor when the CheckBox control is focused.")> <DefaultValue(GetType(Color), "243, 249, 255")>
        Public Property BoxFocusBackColor As Color
            Get
                Return _boxFocusBackColor
            End Get
            Set(value As Color)
                _boxFocusBackColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The box backcolor when the CheckBox control is clicked.")> <DefaultValue(GetType(Color), "51, 153, 255")>
        Public Property BoxMouseDownBackColor As Color
            Get
                Return _boxMouseDownBackColor
            End Get
            Set(value As Color)
                _boxMouseDownBackColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The box border color in the normal state.")> <DefaultValue(GetType(Color), "30, 30, 30")>
        Public Property BoxNormalBorderColor As Color
            Get
                Return _boxNormalBorderColor
            End Get
            Set(value As Color)
                _boxNormalBorderColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The box border color when the CheckBox control is focused.")> <DefaultValue(GetType(Color), "51, 153, 255")>
        Public Property BoxFocusBorderColor As Color
            Get
                Return _boxFocusBorderColor
            End Get
            Set(value As Color)
                _boxFocusBorderColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The box border color when the CheckBox control is clicked.")> <DefaultValue(GetType(Color), "51, 153, 255")>
        Public Property BoxMouseDownBorderColor As Color
            Get
                Return _boxMouseDownBorderColor
            End Get
            Set(value As Color)
                _boxMouseDownBorderColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The CheckBox check-mark color in the normal state.")> <DefaultValue(GetType(Color), "30, 30, 30")>
        Public Property CheckMarkNormalColor As Color
            Get
                Return _checkMarkNormalColor
            End Get
            Set(value As Color)
                _checkMarkNormalColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The CheckBox check-mark color when the CheckBox control is focused.")> <DefaultValue(GetType(Color), "30, 30, 30")>
        Public Property CheckMarkFocusColor As Color
            Get
                Return _checkMarkFocusColor
            End Get
            Set(value As Color)
                _checkMarkFocusColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The CheckBox check-mark color when the CheckBox control is clicked.")> <DefaultValue(GetType(Color), "243, 249, 255")>
        Public Property CheckMarkMouseDownColor As Color
            Get
                Return _checkMarkMouseDownColor
            End Get
            Set(value As Color)
                _checkMarkMouseDownColor = value
                Invalidate()
            End Set
        End Property
    
        <Localizable(True)> <Category("Flat CheckBox")> <Description("The CheckBox control focus cues color.")> <DefaultValue(GetType(Color), "Gray")>
        Public Property FocusCuesColor As Color
            Get
                Return _focusCuesColor
            End Get
            Set(value As Color)
                _focusCuesColor = value
                Invalidate()
            End Set
        End Property
    
        <Category("Flat CheckBox")> <Description("The general style of the Flat CheckBox control.")> <DefaultValue(GetType(UITheme), "1")> Public Property Theme As UITheme
            Get
                Return _theme
            End Get
            Set(value As UITheme)
                _theme = value
    
                If _theme = UITheme.DarkBlue Then
    
                    BackColor = Color.FromArgb(37, 37, 38)
                    ForeColor = Color.Gainsboro
                    BoxNormalBackColor = Color.FromArgb(31, 31, 32)
                    BoxFocusBackColor = Color.FromArgb(31, 31, 32)
                    BoxMouseDownBackColor = Color.FromArgb(0, 122, 204)
                    BoxNormalBorderColor = Color.Gainsboro
                    BoxFocusBorderColor = Color.FromArgb(0, 122, 204)
                    BoxMouseDownBorderColor = Color.FromArgb(0, 122, 204)
                    CheckMarkNormalColor = Color.FromArgb(241, 241, 241)
                    CheckMarkFocusColor = Color.FromArgb(241, 241, 241)
                    CheckMarkMouseDownColor = Color.FromArgb(241, 241, 241)
                    FocusCuesColor = Color.Gray
    
                ElseIf _theme = UITheme.LightBlue Then
    
                    BackColor = Color.FromArgb(251, 251, 251)
                    ForeColor = Color.FromArgb(30, 30, 30)
                    BoxNormalBackColor = Color.FromArgb(243, 249, 255)
                    BoxFocusBackColor = Color.FromArgb(243, 249, 255)
                    BoxMouseDownBackColor = Color.FromArgb(51, 153, 255)
                    BoxNormalBorderColor = Color.FromArgb(30, 30, 30)
                    BoxFocusBorderColor = Color.FromArgb(51, 153, 255)
                    BoxMouseDownBorderColor = Color.FromArgb(51, 153, 255)
                    CheckMarkNormalColor = Color.FromArgb(30, 30, 30)
                    CheckMarkFocusColor = Color.FromArgb(30, 30, 30)
                    CheckMarkMouseDownColor = Color.FromArgb(243, 249, 255)
                    FocusCuesColor = Color.Gray
    
                End If
    
                Invalidate()
    
            End Set
        End Property
    
    #End Region
    
    #Region "Private Methods"
    
        Private Sub ResizeForAutoSize()
            If AutoSize Then SetBoundsCore(Left, Top, Width, Height, BoundsSpecified.Size)
        End Sub
    
        Private Function GetAutoSize() As Size
    
            Dim g = CreateGraphics()
            Dim textSize = g.MeasureString(Text, Font)
            Dim cntrlSize As New Size(CInt(textSize.Width + TEXT_X), CInt(textSize.Height + (TEXT_Y * 2)))
    
            Return cntrlSize
    
        End Function
    
    #End Region
    
    #Region "Overridden Methods"
    
        Protected Overrides Sub OnPaint(e As PaintEventArgs)
    
    #Disable Warning CA1062 ' Validate arguments of public methods
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
    #Enable Warning CA1062 ' Validate arguments of public methods
            e.Graphics.Clear(BackColor)
    
            'Draw CheckBox text
    
            Using b As New SolidBrush(ForeColor)
                e.Graphics.DrawString(Text, Font, b, TEXT_X, TEXT_Y)
            End Using
    
            'Draw box background
    
            Dim boxBackgroundColor As Color
    
            If _isMouseDown Then
                boxBackgroundColor = _boxMouseDownBackColor
            ElseIf Focused OrElse _isMouseEnter Then
                boxBackgroundColor = _boxFocusBackColor
            Else
                boxBackgroundColor = _boxNormalBackColor
            End If
    
            Using b As New SolidBrush(boxBackgroundColor)
                e.Graphics.FillRectangle(b, BOX_X, BOX_Y, BOX_WIDTH, BOX_HEIGHT)
            End Using
    
            'Draw check mark
    
            If Checked Then
    
                Dim checkMarkColor As Color
    
                If _isMouseDown Then
                    checkMarkColor = _checkMarkMouseDownColor
                ElseIf Focused OrElse _isMouseEnter Then
                    checkMarkColor = _checkMarkFocusColor
                Else
                    checkMarkColor = _checkMarkNormalColor
                End If
    
                Dim rectCheck = New Rectangle(BOX_X + 2, BOX_Y + 3, BOX_WIDTH - 4, BOX_HEIGHT - 6)
    
                Using p = New Pen(checkMarkColor, 2)
                    e.Graphics.DrawLines(p, New Point() {New Point(rectCheck.Left, rectCheck.Bottom - CInt(rectCheck.Height / 2)), New Point(rectCheck.Left + CInt(rectCheck.Width / 3), rectCheck.Bottom), New Point(rectCheck.Right, rectCheck.Top)})
                End Using
    
            End If
    
            'Draw box border
    
            Dim boxBorderColor As Color
    
            If _isMouseDown Then
                boxBorderColor = _boxMouseDownBorderColor
            ElseIf Focused OrElse _isMouseEnter Then
                boxBorderColor = _boxFocusBorderColor
            Else
                boxBorderColor = _boxNormalBorderColor
            End If
    
            Using p = New Pen(boxBorderColor)
                e.Graphics.DrawRectangle(p, BOX_X, BOX_Y, BOX_WIDTH, BOX_HEIGHT)
            End Using
    
            'Draw focus cues
    
            If Focused Then
    
                Dim textSize = e.Graphics.MeasureString(Text, Font)
    
                Dim focusRect = New Rectangle(TEXT_X - 1, TEXT_Y - 1, CInt(textSize.Width), CInt(textSize.Height))
                focusRect.Inflate(-1, -1)
    
                Using p As New Pen(_focusCuesColor) With {.DashStyle = DashStyle.Dot}
                    e.Graphics.SmoothingMode = SmoothingMode.Default
                    e.Graphics.DrawRectangle(p, focusRect)
                End Using
    
            End If
    
            ResizeForAutoSize()
    
        End Sub
    
        Public Overrides Function GetPreferredSize(proposedSize As Size) As Size
            Return GetAutoSize()
        End Function
    
        Protected Overrides Sub SetBoundsCore(x As Integer, y As Integer, width As Integer, height As Integer, specified As BoundsSpecified)
    
            If AutoSize AndAlso (specified And BoundsSpecified.Size) <> 0 Then
                Dim cntrlSize = GetAutoSize()
                width = cntrlSize.Width
                height = cntrlSize.Height
            End If
    
            MyBase.SetBoundsCore(x, y, width, height, specified)
    
        End Sub
    
        Protected Overrides Sub OnResize(e As EventArgs)
            MyBase.OnResize(e)
            Invalidate()
        End Sub
    
        Protected Overrides Sub OnMouseEnter(eventargs As EventArgs)
    
            MyBase.OnMouseEnter(eventargs)
    
            _isMouseEnter = True
            Invalidate()
    
        End Sub
    
        Protected Overrides Sub OnMouseLeave(eventargs As EventArgs)
    
            MyBase.OnMouseLeave(eventargs)
    
            _isMouseEnter = False
            Invalidate()
    
        End Sub
    
        Protected Overrides Sub OnMouseDown(mevent As MouseEventArgs)
    
            MyBase.OnMouseDown(mevent)
    
            _isMouseDown = True
            Invalidate()
    
        End Sub
    
        Protected Overrides Sub OnMouseUp(mevent As MouseEventArgs)
    
            MyBase.OnMouseUp(mevent)
    
            _isMouseDown = False
            Invalidate()
    
        End Sub
    
        <DefaultValue(GetType(Color), "251, 251, 251")> Public Overrides Property BackColor As Color
            Get
                Return MyBase.BackColor
            End Get
            Set(value As Color)
                MyBase.BackColor = value
            End Set
        End Property
    
        <DefaultValue(GetType(Color), "30, 30, 30")> Public Overrides Property ForeColor As Color
            Get
                Return MyBase.ForeColor
            End Get
            Set(value As Color)
                MyBase.ForeColor = value
            End Set
        End Property
    
    #End Region
    
    End Class
    
    End Namespace
    

主题枚举

'Copyright (c) Smart PC Utilities, Ltd.
'All rights reserved.

Namespace FlatUI

    Public Enum UITheme As Integer

        ''' <summary>
        ''' Undefined style
        ''' </summary>
        Undefined = -1

        ''' <summary>
        ''' Visual Studio 2019 Dark style
        ''' </summary>
        DarkBlue = 0

        ''' <summary>
        ''' Visual Studio 2019 Light style
        ''' </summary>
        LightBlue = 1

    End Enum

End Namespace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接