SurRadio.cs 5.8 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 SurRadio : BaseCtl
    {
        private bool _check;
        private RectangleF _switchRect = new RectangleF();
        private RectangleF _switchPoint = new RectangleF();
        private RectangleF _textRect = new RectangleF();
        private int _radius = 9;     //半径
        private int _diameter = 18;  //直径
        private string _text = "";

        /// <summary>
        /// 单选框控件
        /// </summary>
        public SurRadio()
        {
            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();
                if (_check)
                {
                    SetGroup();
                    CheckedChanged?.Invoke(this);
                }
            }
            get
            {
                return _check;
            }
        }

        /// <summary>
        /// 相同的内容为一组
        /// </summary>
        [Browsable(true), Category(""), Description("相同的内容为一组,同一组的单选按钮只能选中一个。"), DefaultValue("")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Group { set; get; }

        /// <summary>
        /// 圆的直径
        /// </summary>
        [Browsable(true), Category(""), Description("圆的直径"), DefaultValue(18)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int Diameter
        {
            get
            {
                return _diameter;
            }
            set
            {
                _diameter = value;
                _radius = _diameter / 2;
                CalcSize();
                Refresh();
            }
        }


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

            _switchRect = new RectangleF(6, (Height - _diameter) / 2f, _diameter, _diameter);
            SizeF sf = CreateGraphics().MeasureString(Text, Font);
            _textRect = new RectangleF(_switchRect.X + _switchRect.Width + 6, (Height - sf.Height) / 2f, sf.Width, sf.Height);

            int d = _diameter - 6;
            if (_check)
                _switchPoint = new RectangleF(_switchRect.X + _radius - d / 2f, _switchRect.Y + _radius - d / 2f, d, d);

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

        private void SurRadio_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);
                g.DrawEllipse(Common.BLUE_PEN, _switchRect);
            }
            else
            {
                if (BorderWidth > 0)
                    g.DrawRectangle(BorderOutsidePen, BorderRect);
                g.DrawEllipse(Common.FORE_PEN, _switchRect);
            }
           
            if (_check && Enabled)
                g.FillEllipse(Common.BLUE_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 SurRadio_MouseDown(object sender, MouseEventArgs e)
        {
            if (!Enabled) return;
            Checked = true;
            CalcSize();
            Refresh();
            CheckedChanged?.Invoke(this);
        }

        private void SurRadio_MouseUp(object sender, MouseEventArgs e)
        {

        }

        private void SetGroup()
        {
            if (Parent == null) return;
            foreach (Control ctl in Parent.Controls)
            {
                if (ctl is SurRadio)
                {
                    SurRadio rdo = (SurRadio)ctl;
                    if (rdo == this) continue;
                    if (rdo.Group == Group)
                    {
                        if (rdo.Checked)
                        {
                            rdo.Checked = false;
                            break;
                        }
                    }
                }
            }
        }


    }
}