SurChoose.cs 6.2 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("Text")]
    [DefaultEvent("SelectedIndexChanged")]
    public partial class SurChoose : BaseCtl
    {
        private RectangleF[] _btnRect;
        private string[] _btnText;
        private RectangleF[] _btnTextRect;
        private int _indexOver = -1;
        private int _index = -1;
        private const int SPACE = 3;

        /// <summary>
        /// 选择控件
        /// </summary>
        public SurChoose()
        {
            InitializeComponent();
        }


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


        //==========属性==========
        /// <summary>
        /// 当前选定项从零开始的索引
        /// </summary>
        [Browsable(false), Category(""), Description("当前选定项从零开始的索引")]
        public int SelectedIndex
        {
            set
            {
                _index = value;
                Refresh();
                if (Enabled)
                    SelectedIndexChanged?.Invoke(this);
            }
            get => _index;
        }

        /// <summary>
        /// 当前选定项的文本
        /// </summary>
        [Browsable(false), Category(""), Description("当前选定项的文本")]
        public string SelectedText
        {
            set
            {
                if (_btnText != null)
                {
                    int idx = Array.FindIndex(_btnText, s => s == value);
                    if (idx > -1) SelectedIndex = idx;
                }
            }
            get
            {
                if (_btnText == null)
                    return "";
                else if (_index < 0)
                    return "";
                else
                    return _btnText[_index];
            }
        }


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

            _btnText = Text.Split(',');
            int count = _btnText.Length;
            _btnRect = new RectangleF[count];
            _btnTextRect = new RectangleF[count];
            float w = Width - BorderWidth - BorderWidth;
            float h = Height - BorderWidth - BorderWidth;
            float ww = (w - SPACE * (count + 1)) / count;
            float hh = h - SPACE - SPACE;
            Graphics g = CreateGraphics();
            SizeF sf;

            for (int i = 0; i < count; i++)
            {
                _btnRect[i] = new RectangleF(BorderWidth + SPACE * (i + 1) + ww * i, BorderWidth + SPACE, ww, hh);
                sf = g.MeasureString(_btnText[i], Font);
                _btnTextRect[i] = new RectangleF(_btnRect[i].X + (_btnRect[i].Width - sf.Width) / 2, _btnRect[i].Y + (_btnRect[i].Height - sf.Height) / 2, sf.Width, sf.Height);
            }




        }

        private void SurChoose_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
            {
                _indexOver = -1;  //避免移动太快没有执行MouseMove
                if (BorderWidth > 0)
                    g.DrawRectangle(BorderOutsidePen, BorderRect);
            }

            for (int i = 0; i < _btnRect.Length; i++)
            {
                if (Enabled)
                {
                    if (i == _index)
                        g.FillRectangle(Common.BLUE_BRUSH, _btnRect[i]);
                    else if (i == _indexOver)
                        g.FillRectangle(Common.OVER_BRUSH, _btnRect[i]);
                    g.DrawString(_btnText[i], Font, Common.FORE_BRUSH, _btnTextRect[i]);
                }
                else
                {
                    g.DrawString(_btnText[i], Font, Common.BORDER_BRUSH, _btnTextRect[i]);
                }
            }

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

        private void SurChoose_Load(object sender, EventArgs e)
        {
            _index = -1;
        }

        private void SurChoose_MouseMove(object sender, MouseEventArgs e)
        {
            if (!Enabled) return;
            int move = -1;

            for (int i = 0; i < _btnRect.Length; i++)
            {
                if (_btnRect[i].Contains(e.Location))
                {
                    move = i;
                    break;
                }
            }

            if (_indexOver != move)
            {
                _indexOver = move;
                Refresh();
            }
        }

        private void SurChoose_MouseDown(object sender, MouseEventArgs e)
        {
            if (!Enabled) return;
            if (e.Button == MouseButtons.Left)
            {
                if (_indexOver > -1)
                {
                    _index = _indexOver;
                    Refresh();
                }
            }
        }

        private void SurChoose_MouseUp(object sender, MouseEventArgs e)
        {
            if (!Enabled) return;
            if (e.Button == MouseButtons.Left)
            {
                if (_indexOver > -1 && _index > -1)
                {
                    SelectedIndexChanged?.Invoke(this);
                }
            }
        }
    }
}