SurCheck.cs 5.9 KB
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Asa.Face
{
    /// <summary>
    /// 复选框控件
    /// </summary>
    [DefaultProperty("Checked")]
    [DefaultEvent("CheckedChanged")]
    public partial class SurCheck : BaseCtl
    {
        private bool _check;
        private GraphicsPath _switchPath = new GraphicsPath();
        private RectangleF _switchPoint = new RectangleF();
        private RectangleF _textRect = new RectangleF();
        private string _text = "";
        private int _radius = 9;
        private int _between = 20;

        private static readonly Pen SWITCH_PEN = new Pen(Common.FORE_COLOR, 1);


        /// <summary>
        /// 复选框控件
        /// </summary>
        public SurCheck()
        {
            InitializeComponent();
        }


        //==========事件==========
        /// <summary>
        /// Check属性更改时发生
        /// </summary>
        [Browsable(true), Category(""), Description("Check属性更改时发生")]
        public event MyEvent.Changed CheckedChanged;


        //==========属性==========
        /// <summary>
        /// 组件是否处于选中状态
        /// </summary>
        [Browsable(true), Category(""), Description("组件是否处于选中状态"), DefaultValue(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public bool Checked
        {
            set
            {
                _check = value;
                CalcSize();
                Refresh();
                CheckedChanged?.Invoke(this);
            }
            get
            {
                return _check;
            }
        }

        /// <summary>
        /// 左右半圆的半径
        /// </summary>
        [Browsable(true), Category(""), Description("左右半圆的半径"), DefaultValue(9)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int Radius
        {
            get
            {
                return _radius;
            }
            set
            {
                _radius = value;
                CalcSize();
                Refresh();
            }
        }

        /// <summary>
        /// 左右半圆的圆心距离
        /// </summary>
        [Browsable(true), Category(""), Description("左右半圆的圆心距离"), DefaultValue(20)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int CircleSpace
        {
            set
            {
                _between = value;
                CalcSize();
                Refresh();
            }
            get
            {
                return _between;
            }
        }


        //==========私有==========
        /// <summary>
        /// 计算大小
        /// </summary>
        protected override void CalcSize()
        {
            base.CalcSize();

            int diameter = _radius * 2;  //直径
            RectangleF rect1 = new RectangleF(6, (Height - diameter) / 2f, diameter, diameter);
            RectangleF rect2 = new RectangleF(6 + _between, (Height - diameter) / 2f, diameter, diameter);
            SizeF sf = CreateGraphics().MeasureString(Text, Font);
            _textRect = new RectangleF(rect2.X + rect2.Width + 6, (Height - sf.Height) / 2f, sf.Width, sf.Height);

            _switchPath = new GraphicsPath();
            _switchPath.AddArc(rect1, 90, 180);
            _switchPath.AddLine(rect1.X + _radius, rect1.Y, rect2.X + _radius, rect2.Y);
            _switchPath.AddArc(rect2, -90, 180);
            _switchPath.AddLine(rect2.X + _radius, rect2.Y + diameter, rect1.X + _radius, rect1.Y + diameter);

            int d = _radius * 2 - 6;
            if (_check)
                _switchPoint = new RectangleF(rect2.X + _radius - d / 2f, rect2.Y + _radius - d / 2f, d, d);
            else
                _switchPoint = new RectangleF(rect1.X + _radius - d / 2f, rect1.Y + _radius - d / 2f, d, d);

            _text = Text;
            string[] arr = Text.Split(',');
            if (arr.Length == 2)
                _text = _check ? arr[1] : arr[0];
        }

        private void FlatCheck_Paint(object sender, PaintEventArgs e)
        {
            BufferedGraphicsContext current = BufferedGraphicsManager.Current;
            BufferedGraphics bg = current.Allocate(e.Graphics, e.ClipRectangle);
            Graphics g = bg.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.Clear(Common.BACK_COLOR);  //背景

            //边框
            if (Inside && Enabled)
            {
                if (BorderWidth > 0)
                    g.DrawRectangle(BorderInsidePen, BorderRect);
            }
            else
            {
                if (BorderWidth > 0)
                    g.DrawRectangle(BorderOutsidePen, BorderRect);
            }

            //开关
            if (_check && Enabled)
                g.FillPath(Common.BLUE_BRUSH, _switchPath);
            else
                g.DrawPath(SWITCH_PEN, _switchPath);

            //开关点
            if (Enabled)
                g.FillEllipse(Common.FORE_BRUSH, _switchPoint);

            //文本
            if (Enabled)
                g.DrawString(_text, Font, Common.FORE_BRUSH, _textRect);
            else
                g.DrawString(_text, Font, Common.BORDER_BRUSH, _textRect);

            bg.Render();
            bg.Dispose();



        }

        private void FlatCheck_MouseDown(object sender, MouseEventArgs e)
        {
            if (!Enabled) return;
            if (e.Button == MouseButtons.Left)
                Checked = !Checked;
        }


    }
}