LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# WinForm中使用GDI+自定义CheckBox控件的实现

admin
2025年3月29日 9:44 本文热度 41

在WinForm开发中,默认的CheckBox控件外观比较单调。通过继承CheckBox类并重写OnPaint方法,我们可以使用GDI+绘制出更加美观的自定义CheckBox控件。

完整代码实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppControls
{
    publicclass ModernCheckBox : CheckBox
    {
        // 定义三种状态的颜色  
        private Color checkedColor = Color.MediumSlateBlue;
        private Color unCheckedColor = Color.Gray;
        private Color indeterminateColor = Color.RosyBrown;

        #region 属性  

        // 选中状态颜色  
        public Color CheckedColor
        {
            get => checkedColor;
            set
            {
                checkedColor = value;
                Invalidate();
            }
        }

        // 未选中状态颜色  
        public Color UnCheckedColor
        {
            get => unCheckedColor;
            set
            {
                unCheckedColor = value;
                Invalidate();
            }
        }

        // 不确定状态颜色  
        public Color IndeterminateColor
        {
            get => indeterminateColor;
            set
            {
                indeterminateColor = value;
                Invalidate();
            }
        }

        #endregion

        public ModernCheckBox()
        
{
            // 设置控件最小高度  
            MinimumSize = new Size(021);
            // 启用三态选择  
            this.ThreeState = true;
        }

        protected override void OnPaint(PaintEventArgs pevent)
        
{
            // 获取绘图上下文  
            Graphics graphics = pevent.Graphics;
            // 设置抗锯齿模式  
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // 定义复选框的尺寸参数  
            float borderSize = 18F;        // 外边框大小  
            float checkSize = 12F;         // 选中标记大小  
            float indeterminateHeight = 2F// 不确定状态线条高度  

            // 创建外边框矩形  
            RectangleF borderRect = new RectangleF()
            {
                X = 0.5F,
                Y = (Height - borderSize) / 2,    // 垂直居中  
                Width = borderSize,
                Height = borderSize
            };

            // 创建选中标记矩形  
            RectangleF checkRect = new RectangleF()
            {
                X = borderRect.X + ((borderRect.Width - checkSize) / 2),
                Y = (Height - checkSize) / 2,
                Width = checkSize,
                Height = checkSize
            };

            // 创建不确定状态矩形  
            RectangleF indeterminateRect = new RectangleF()
            {
                X = borderRect.X + 4,
                Y = (Height - indeterminateHeight) / 2,
                Width = borderSize - 8,
                Height = indeterminateHeight
            };

            // 使用using语句确保资源正确释放  
            using (Pen borderPen = new Pen(checkedColor, 1.6F))
            using (SolidBrush checkBrush = new SolidBrush(checkedColor))
            using (SolidBrush indeterminateBrush = new SolidBrush(indeterminateColor))
            using (SolidBrush textBrush = new SolidBrush(ForeColor))
            {
                // 清除背景  
                graphics.Clear(BackColor);

                // 根据CheckState绘制不同状态  
                switch (CheckState)
                {
                    case CheckState.Checked:
                        // 绘制选中状态  
                        graphics.DrawRectangle(borderPen,
                            borderRect.X, borderRect.Y,
                            borderRect.Width, borderRect.Height);
                        graphics.FillRectangle(checkBrush, checkRect);
                        break;

                    case CheckState.Indeterminate:
                        // 绘制不确定状态  
                        borderPen.Color = indeterminateColor;
                        graphics.DrawRectangle(borderPen,
                            borderRect.X, borderRect.Y,
                            borderRect.Width, borderRect.Height);
                        graphics.FillRectangle(indeterminateBrush, indeterminateRect);
                        break;

                    case CheckState.Unchecked:
                        // 绘制未选中状态  
                        borderPen.Color = unCheckedColor;
                        graphics.DrawRectangle(borderPen,
                            borderRect.X, borderRect.Y,
                            borderRect.Width, borderRect.Height);
                        break;
                }

                // 绘制文本  
                graphics.DrawString(Text, Font, textBrush,
                    borderSize + 8,    // 文本位置X坐标  
                    (Height - TextRenderer.MeasureText(Text, Font).Height) / 2    // 文本垂直居中  
                );
            }
        }

        protected override void OnResize(EventArgs e)
        
{
            base.OnResize(e);
            // 根据文本自动调整控件宽度  
            Width = TextRenderer.MeasureText(Text, Font).Width + 30;
        }

        // 添加鼠标悬停效果  
        protected override void OnMouseEnter(EventArgs eventargs)
        
{
            base.OnMouseEnter(eventargs);
            this.Cursor = Cursors.Hand;
        }

        protected override void OnMouseLeave(EventArgs eventargs)
        
{
            base.OnMouseLeave(eventargs);
            this.Cursor = Cursors.Default;
        }
    }
}

增加动画过渡与Enabled = false效果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppControls
{
    publicclass ModernCheckBox : CheckBox
    {
        // 定义三种状态的颜色  
        private Color checkedColor = Color.MediumSlateBlue;
        private Color unCheckedColor = Color.Gray;
        private Color indeterminateColor = Color.RosyBrown;

        private Color disabledColor = Color.LightGray;        // 禁用状态颜色  
        private Color disabledTextColor = Color.DarkGray;     // 禁用状态文本颜色  

        // 动画相关字段  
        private System.Windows.Forms.Timer animationTimer;
        privatefloat currentAnimationValue = 0f;
        privatebool isAnimating = false;
        private CheckState previousState;
        private Color fromColor;
        private Color toColor;
        privateconstint ANIMATION_DURATION = 200// 动画持续时间(毫秒)  
        privateconstint TIMER_INTERVAL = 16// 约60fps  
        privatefloat animationStep;

        #region 属性  

        // 选中状态颜色  
        public Color CheckedColor
        {
            get => checkedColor;
            set
            {
                checkedColor = value;
                Invalidate();
            }
        }

        // 未选中状态颜色  
        public Color UnCheckedColor
        {
            get => unCheckedColor;
            set
            {
                unCheckedColor = value;
                Invalidate();
            }
        }

        // 不确定状态颜色  
        public Color IndeterminateColor
        {
            get => indeterminateColor;
            set
            {
                indeterminateColor = value;
                Invalidate();
            }
        }

        // 禁用状态颜色属性  
        public Color DisabledColor
        {
            get => disabledColor;
            set
            {
                disabledColor = value;
                Invalidate();
            }
        }

        // 禁用状态文本颜色属性  
        public Color DisabledTextColor
        {
            get => disabledTextColor;
            set
            {
                disabledTextColor = value;
                Invalidate();
            }
        }

        #endregion

        public ModernCheckBox()
        
{
            MinimumSize = new Size(021);
            this.ThreeState = true;

            // 初始化动画计时器  
            animationTimer = new System.Windows.Forms.Timer();
            animationTimer.Interval = TIMER_INTERVAL;
            animationTimer.Tick += AnimationTimer_Tick;

            // 计算每次动画步进值  
            animationStep = 1f / (ANIMATION_DURATION / TIMER_INTERVAL);

            previousState = CheckState;
        }

        private void AnimationTimer_Tick(object sender, EventArgs e)
        
{
            if (isAnimating)
            {
                currentAnimationValue += animationStep;

                if (currentAnimationValue >= 1f)
                {
                    currentAnimationValue = 1f;
                    isAnimating = false;
                    animationTimer.Stop();
                }

                Invalidate();
            }
        }

        protected override void OnCheckStateChanged(EventArgs e)
        
{
            // 开始新的动画  
            StartNewAnimation();
            base.OnCheckStateChanged(e);
        }

        private void StartNewAnimation()
        
{
            // 设置起始颜色  
            fromColor = GetCurrentStateColor(previousState);
            // 设置目标颜色  
            toColor = GetCurrentStateColor(CheckState);

            // 重置动画参数  
            currentAnimationValue = 0f;
            isAnimating = true;

            // 启动动画计时器  
            animationTimer.Start();

            // 更新前一个状态  
            previousState = CheckState;
        }

        private Color GetCurrentStateColor(CheckState state)
        
{
            if (!Enabled) return disabledColor;

            switch (state)
            {
                case CheckState.Checked:
                    return checkedColor;
                case CheckState.Indeterminate:
                    return indeterminateColor;
                default:
                    return unCheckedColor;
            }
        }


        protected override void OnPaint(PaintEventArgs pevent)
        
{
            Graphics graphics = pevent.Graphics;
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            float borderSize = 18F;
            float checkSize = 12F;
            float indeterminateHeight = 2F;

            // 创建外边框矩形  
            RectangleF borderRect = new RectangleF()
            {
                X = 0.5F,
                Y = (Height - borderSize) / 2,
                Width = borderSize,
                Height = borderSize
            };

            // 创建选中标记矩形,添加动画缩放效果  
            float animatedCheckSize = isAnimating ?
                checkSize * currentAnimationValue :
                (CheckState == CheckState.Checked ? checkSize : 0);

            RectangleF checkRect = new RectangleF()
            {
                X = borderRect.X + ((borderRect.Width - animatedCheckSize) / 2),
                Y = (Height - animatedCheckSize) / 2,
                Width = animatedCheckSize,
                Height = animatedCheckSize
            };

            // 创建不确定状态矩形  
            RectangleF indeterminateRect = new RectangleF()
            {
                X = borderRect.X + 4,
                Y = (Height - indeterminateHeight) / 2,
                Width = borderSize - 8,
                Height = indeterminateHeight
            };

            // 计算当前动画颜色  
            Color currentBorderColor;
            Color currentFillColor;
            Color currentTextColor = Enabled ? ForeColor : disabledTextColor;

            if (isAnimating)
            {
                // 在动画过程中对颜色进行插值  
                currentBorderColor = InterpolateColor(fromColor, toColor, currentAnimationValue);
                currentFillColor = currentBorderColor;
            }
            else
            {
                currentBorderColor = GetCurrentStateColor(CheckState);
                currentFillColor = currentBorderColor;
            }

            using (Pen borderPen = new Pen(currentBorderColor, 1.6F))
            using (SolidBrush fillBrush = new SolidBrush(currentFillColor))
            using (SolidBrush textBrush = new SolidBrush(currentTextColor))
            {
                graphics.Clear(BackColor);

                // 绘制边框  
                graphics.DrawRectangle(borderPen,
                    borderRect.X, borderRect.Y,
                    borderRect.Width, borderRect.Height);

                // 根据状态绘制内部  
                switch (CheckState)
                {
                    case CheckState.Checked:
                        if (animatedCheckSize > 0)
                            graphics.FillRectangle(fillBrush, checkRect);
                        break;

                    case CheckState.Indeterminate:
                        graphics.FillRectangle(fillBrush, indeterminateRect);
                        break;
                }

                // 绘制文本  
                if (!Enabled)
                {
                    textBrush.Color = Color.FromArgb(128, disabledTextColor);
                }

                graphics.DrawString(Text, Font, textBrush,
                    borderSize + 8,
                    (Height - TextRenderer.MeasureText(Text, Font).Height) / 2
                );
            }
        }

        // 颜色插值方法  
        private Color InterpolateColor(Color from, Color to, float progress)
        
{
            int r = (int)(from.R + (to.R - from.R) * progress);
            int g = (int)(from.G + (to.G - from.G) * progress);
            int b = (int)(from.B + (to.B - from.B) * progress);
            int a = (int)(from.A + (to.A - from.A) * progress);

            return Color.FromArgb(a, r, g, b);
        }
        protected override void OnEnabledChanged(EventArgs e)
        
{
            base.OnEnabledChanged(e);
            Invalidate(); // 重绘控件  
        }

        protected override void OnResize(EventArgs e)
        
{
            base.OnResize(e);
            // 根据文本自动调整控件宽度  
            Width = TextRenderer.MeasureText(Text, Font).Width + 30;
        }

        // 添加鼠标悬停效果  
        protected override void OnMouseEnter(EventArgs eventargs)
        
{
            base.OnMouseEnter(eventargs);
            if (Enabled) // 仅在启用状态下改变光标  
            {
                Cursor = Cursors.Hand;
            }
        }

        protected override void OnMouseLeave(EventArgs eventargs)
        
{
            base.OnMouseLeave(eventargs);
            this.Cursor = Cursors.Default;
        }

        protected override void Dispose(bool disposing)
        
{
            if (disposing)
            {
                animationTimer?.Dispose();
            }
            base.Dispose(disposing);
        }

    }
}

注意事项

这个自定义CheckBox控件实现了一个现代化的外观,通过GDI+的绘制功能,我们可以完全控制控件的视觉效果。你可以根据需要修改颜色、大小等参数来适应不同的应用场景。


阅读原文:原文链接


该文章在 2025/3/31 11:25:11 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved