[转]下拉按钮 C#_Winform 自定义控件

时间:2014-06-07 02:40:18   收藏:0   阅读:424
[https://workspaces.codeproject.com/elia-sarti/splitbutton-an-xp-style-dropdown-split-button]
bubuko.com,布布扣
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace SplitButtonDemo
{
    public class SplitButton : Button
    {
        #region Fields

        private bool _DoubleClickedEnabled;

        private bool _AlwaysDropDown;
        private bool _AlwaysHoverChange;

        private bool _CalculateSplitRect = true;
        private bool _FillSplitHeight = true;
        private int _SplitHeight;
        private int _SplitWidth;

        private String _NormalImage;
        private String _HoverImage;
        private String _ClickedImage;
        private String _DisabledImage;
        private String _FocusedImage;

        private ImageList _DefaultSplitImages;


        [Browsable(true)]
        [Category("Action")]
        [Description("Occurs when the button part of the SplitButton is clicked.")]
        public event EventHandler ButtonClick;

        [Browsable(true)]
        [Category("Action")]
        [Description("Occurs when the button part of the SplitButton is clicked.")]
        public event EventHandler ButtonDoubleClick;

        #endregion


        #region Properties
        /// <summary>
        /// 
        /// </summary>
        [Category("Behavior")]
        [Description("Indicates whether the double click event is raised on the SplitButton")]
        [DefaultValue(false)]
        public bool DoubleClickedEnabled
        {
            get
            {
                return _DoubleClickedEnabled;
            }
            set
            {
                _DoubleClickedEnabled = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button")]
        [Description("Indicates whether the SplitButton always shows the drop down menu even if the button part of the SplitButton is clicked.")]
        [DefaultValue(false)]
        public bool AlwaysDropDown
        {
            get
            {
                return _AlwaysDropDown;
            }
            set
            {
                _AlwaysDropDown = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button")]
        [Description("Indicates whether the SplitButton always shows the Hover image status in the split part even if the button part of the SplitButton is hovered.")]
        [DefaultValue(false)]
        public bool AlwaysHoverChange
        {
            get
            {
                return _AlwaysHoverChange;
            }
            set
            {
                _AlwaysHoverChange = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button")]
        [Description("Indicates whether the split rectange must be calculated (basing on Split image size)")]
        [DefaultValue(true)]
        public bool CalculateSplitRect
        {
            get
            {
                return _CalculateSplitRect;
            }
            set
            {
                bool flag1 = _CalculateSplitRect;

                _CalculateSplitRect = value;

                if (flag1 != _CalculateSplitRect)
                {
                    if (_SplitWidth > 0 && _SplitHeight > 0)
                    {
                        InitDefaultSplitImages(true);
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [fill split height].
        /// </summary>
        /// <value><c>true</c> if [fill split height]; otherwise, <c>false</c>.</value>
        [Category("Split Button")]
        [Description("Indicates whether the split height must be filled to the button height even if the split image height is lower.")]
        [DefaultValue(true)]
        public bool FillSplitHeight
        {
            get
            {
                return _FillSplitHeight;
            }
            set
            {
                _FillSplitHeight = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button")]
        [Description("The split height (ignored if CalculateSplitRect is setted to true).")]
        [DefaultValue(0)]
        public int SplitHeight
        {
            get
            {
                return _SplitHeight;
            }
            set
            {
                _SplitHeight = value;

                if (!_CalculateSplitRect)
                {
                    if (_SplitWidth > 0 && _SplitHeight > 0)
                    {
                        InitDefaultSplitImages(true);
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button")]
        [Description("The split width (ignored if CalculateSplitRect is setted to true).")]
        [DefaultValue(0)]
        public int SplitWidth
        {
            get
            {
                return _SplitWidth;
            }
            set
            {
                _SplitWidth = value;

                if (!_CalculateSplitRect)
                {
                    if (_SplitWidth > 0 && _SplitHeight > 0)
                    {
                        InitDefaultSplitImages(true);
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button Images")]
        [Description("The Normal status image name in the ImageList.")]
        [DefaultValue("")]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), RefreshProperties(RefreshProperties.Repaint), TypeConverter(typeof(ImageKeyConverter))]
        public String NormalImage
        {
            get
            {
                return _NormalImage;
            }
            set
            {
                _NormalImage = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button Images")]
        [Description("The Hover status image name in the ImageList.")]
        [DefaultValue("")]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), RefreshProperties(RefreshProperties.Repaint), TypeConverter(typeof(ImageKeyConverter))]
        public String HoverImage
        {
            get
            {
                return _HoverImage;
            }
            set
            {
                _HoverImage = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button Images")]
        [Description("The Clicked status image name in the ImageList.")]
        [DefaultValue("")]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), RefreshProperties(RefreshProperties.Repaint), TypeConverter(typeof(ImageKeyConverter))]
        public String ClickedImage
        {
            get
            {
                return _ClickedImage;
            }
            set
            {
                _ClickedImage = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button Images")]
        [Description("The Disabled status image name in the ImageList.")]
        [DefaultValue("")]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), RefreshProperties(RefreshProperties.Repaint), TypeConverter(typeof(ImageKeyConverter))]
        public String DisabledImage
        {
            get
            {
                return _DisabledImage;
            }
            set
            {
                _DisabledImage = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Category("Split Button Images")]
        [Description("The Focused status image name in the ImageList.")]
        [DefaultValue("")]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), RefreshProperties(RefreshProperties.Repaint), TypeConverter(typeof(ImageKeyConverter))]
        public String FocusedImage
        {
            get
            {
                return _FocusedImage;
            }
            set
            {
                _FocusedImage = value;
            }
        }

        #endregion


        #region Construction

        public SplitButton()
        {
            InitializeComponent();
        }

        #endregion


        #region Methods

        protected override void OnCreateControl()
        {
            InitDefaultSplitImages();

            if (this.ImageList == null)
            {
                this.ImageList = _DefaultSplitImages;
            }

            if (Enabled)
            {
                SetSplit(_NormalImage);
            }
            else
            {
                SetSplit(_DisabledImage);
            }
            
            base.OnCreateControl();
        }

        private void InitDefaultSplitImages()
        {
            InitDefaultSplitImages(false);
        }

        private void InitDefaultSplitImages(bool refresh)
        {
            if (String.IsNullOrEmpty(_NormalImage))
            {
                _NormalImage = "Normal";
            }

            if (String.IsNullOrEmpty(_HoverImage))
            {
                _HoverImage = "Hover";
            }

            if (String.IsNullOrEmpty(_ClickedImage))
            {
                _ClickedImage = "Clicked";
            }

            if (String.IsNullOrEmpty(_DisabledImage))
            {
                _DisabledImage = "Disabled";
            }

            if (String.IsNullOrEmpty(_FocusedImage))
            {
                _FocusedImage = "Focused";
            }

            if (_DefaultSplitImages == null)
            {
                _DefaultSplitImages = new ImageList();
            }

            if (_DefaultSplitImages.Images.Count == 0 || refresh)
            {
                if (_DefaultSplitImages.Images.Count > 0)
                {
                    _DefaultSplitImages.Images.Clear();
                }

                try
                {
                    int w = 0;
                    int h = 0;

                    if (!_CalculateSplitRect && _SplitWidth > 0)
                    {
                        w = _SplitWidth;
                    }
                    else
                    {
                        w = 18;
                    }

                    if (!CalculateSplitRect && SplitHeight > 0)
                    {
                        h = SplitHeight;
                    }
                    else
                    {
                        h = Height;
                    }

                    h -= 8;

                    _DefaultSplitImages.ImageSize = new Size(w, h);

                    int mw = w / 2;
                    mw += (mw % 2);
                    int mh = h / 2;

                    Pen fPen = new Pen(ForeColor, 1);
                    SolidBrush fBrush = new SolidBrush(ForeColor);

                    Bitmap imgN = new Bitmap(w, h);
                    Graphics g = Graphics.FromImage(imgN);

                    g.CompositingQuality = CompositingQuality.HighQuality;

                    g.DrawLine(SystemPens.ButtonShadow, new Point(1, 1), new Point(1, h - 2));
                    g.DrawLine(SystemPens.ButtonFace, new Point(2, 1), new Point(2, h));

                    g.FillPolygon(fBrush, new Point[] { new Point(mw - 2, mh - 1), 
                                                         new Point(mw + 3, mh - 1),
                                                         new Point(mw, mh + 2) });

                    g.Dispose();

                    Bitmap imgH = new Bitmap(w, h);
                    g = Graphics.FromImage(imgH);

                    g.CompositingQuality = CompositingQuality.HighQuality;

                    g.DrawLine(SystemPens.ButtonShadow, new Point(1, 1), new Point(1, h - 2));
                    g.DrawLine(SystemPens.ButtonFace, new Point(2, 1), new Point(2, h));

                    g.FillPolygon(fBrush, new Point[] { new Point(mw - 3, mh - 2), 
                                                         new Point(mw + 4, mh - 2),
                                                         new Point(mw, mh + 2) });

                    g.Dispose();

                    Bitmap imgC = new Bitmap(w, h);
                    g = Graphics.FromImage(imgC);

                    g.CompositingQuality = CompositingQuality.HighQuality;

                    g.DrawLine(SystemPens.ButtonShadow, new Point(1, 1), new Point(1, h - 2));
                    g.DrawLine(SystemPens.ButtonFace, new Point(2, 1), new Point(2, h));

                    g.FillPolygon(fBrush, new Point[] { new Point(mw - 2, mh - 1), 
                                                         new Point(mw + 3, mh - 1),
                                                         new Point(mw, mh + 2) });

                    g.Dispose();

                    Bitmap imgD = new Bitmap(w, h);
                    g = Graphics.FromImage(imgD);

                    g.CompositingQuality = CompositingQuality.HighQuality;

                    g.DrawLine(SystemPens.GrayText, new Point(1, 1), new Point(1, h - 2));

                    g.FillPolygon(new SolidBrush(SystemColors.GrayText), new Point[] { new Point(mw - 2, mh - 1), 
                                                         new Point(mw + 3, mh - 1),
                                                         new Point(mw, mh + 2) });

                    g.Dispose();

                    Bitmap imgF = new Bitmap(w, h);
                    g = Graphics.FromImage(imgF);

                    g.CompositingQuality = CompositingQuality.HighQuality;

                    g.DrawLine(SystemPens.ButtonShadow, new Point(1, 1), new Point(1, h - 2));
                    g.DrawLine(SystemPens.ButtonFace, new Point(2, 1), new Point(2, h));

                    g.FillPolygon(fBrush, new Point[] { new Point(mw - 2, mh - 1), 
                                                         new Point(mw + 3, mh - 1),
                                                         new Point(mw, mh + 2) });

                    g.Dispose();

                    fPen.Dispose();
                    fBrush.Dispose();

                    _DefaultSplitImages.Images.Add(_NormalImage, imgN);
                    _DefaultSplitImages.Images.Add(_HoverImage, imgH);
                    _DefaultSplitImages.Images.Add(_ClickedImage, imgC);
                    _DefaultSplitImages.Images.Add(_DisabledImage, imgD);
                    _DefaultSplitImages.Images.Add(_FocusedImage, imgF);
                }
                catch
                { }
            }
        }

        protected override void OnMouseMove(MouseEventArgs mevent)
        {
            if (_AlwaysDropDown || _AlwaysHoverChange || MouseInSplit())
            {
                if (Enabled)
                {
                    SetSplit(_HoverImage);
                }
            }
            else
            {
                if (Enabled)
                {
                    SetSplit(_NormalImage);
                }
            }

            base.OnMouseMove(mevent);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            if (Enabled)
            {
                SetSplit(_NormalImage);
            }

            base.OnMouseLeave(e);
        }

        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            if (_AlwaysDropDown || MouseInSplit())
            {
                if (Enabled)
                {
                    SetSplit(_ClickedImage);

                    if (this.ContextMenuStrip != null && this.ContextMenuStrip.Items.Count > 0)
                    {
                        this.ContextMenuStrip.Show(this, new Point(0, Height));
                    }
                }
            }
            else
            {
                if (Enabled)
                {
                    SetSplit(_NormalImage);
                }
            }

            base.OnMouseDown(mevent);
        }

        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            if (_AlwaysDropDown || _AlwaysHoverChange || MouseInSplit())
            {
                if (Enabled)
                {
                    SetSplit(_HoverImage);
                }
            }
            else
            {
                if (Enabled)
                {
                    SetSplit(_NormalImage);
                }
            }

            base.OnMouseUp(mevent);
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            if (!Enabled)
            {
                SetSplit(_DisabledImage);
            }
            else
            {
                if (MouseInSplit())
                {
                    SetSplit(_HoverImage);
                }
                else
                {
                    SetSplit(_NormalImage);
                }
            }

            base.OnEnabledChanged(e);
        }

        protected override void OnGotFocus(EventArgs e)
        {
            if (Enabled)
            {
                SetSplit(_FocusedImage);
            }

            base.OnGotFocus(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            if (Enabled)
            {
                SetSplit(_NormalImage);
            }

            base.OnLostFocus(e);
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);

            if (!MouseInSplit() && !_AlwaysDropDown)
            {
                if (ButtonClick != null)
                {
                    ButtonClick(this, e);
                }
            }
        }

        protected override void OnDoubleClick(EventArgs e)
        {
            if (_DoubleClickedEnabled)
            {
                base.OnDoubleClick(e);

                if (!MouseInSplit() && !_AlwaysDropDown)
                {
                    if (ButtonClick != null)
                    {
                        ButtonDoubleClick(this, e);
                    }
                }
            }
        }

        private void SetSplit(String imageName)
        {
            if (imageName != null && ImageList != null && ImageList.Images.ContainsKey(imageName))
            {
                this.ImageKey = imageName;
            }
        }

        public bool MouseInSplit()
        {
            return PointInSplit(PointToClient(MousePosition));
        }

        public bool PointInSplit(Point pt)
        {
            Rectangle splitRect = GetImageRect(_NormalImage);

            if (!_CalculateSplitRect)
            {
                splitRect.Width = _SplitWidth;
                splitRect.Height = _SplitHeight;
            }

            return splitRect.Contains(pt);
        }

        public Rectangle GetImageRect(String imageKey)
        {
                Image currImg = GetImage(imageKey);

                if (currImg != null)
                {
                    int x = 0,
                        y = 0,
                        w = currImg.Width+1,
                        h = currImg.Height+1;

                    if (w > this.Width)
                    {
                        w = this.Width;
                    }

                    if (h > this.Width)
                    {
                        h = this.Width;
                    }

                    switch (ImageAlign)
                    {
                        case ContentAlignment.TopLeft:
                            {
                                x = 0;
                                y = 0;

                                break;
                            }
                        case ContentAlignment.TopCenter:
                            {
                                x = (this.Width - w) / 2;
                                y = 0;

                                if ((this.Width - w) % 2 > 0)
                                {
                                    x += 1;
                                }

                                break;
                            }
                        case ContentAlignment.TopRight:
                            {
                                x = this.Width - w;
                                y = 0;

                                break;
                            }
                        case ContentAlignment.MiddleLeft:
                            {
                                x = 0;
                                y = (this.Height - h) / 2;

                                if ((this.Height - h) % 2 > 0)
                                {
                                    y += 1;
                                }

                                break;
                            }
                        case ContentAlignment.MiddleCenter:
                            {
                                x = (this.Width - w) / 2;
                                y = (this.Height - h) / 2;

                                if ((this.Width - w) % 2 > 0)
                                {
                                    x += 1;
                                }
                                if ((this.Height - h) % 2 > 0)
                                {
                                    y += 1;
                                }

                                break;
                            }
                        case ContentAlignment.MiddleRight:
                            {
                                x = this.Width - w;
                                y = (this.Height - h) / 2;

                                if ((this.Height - h) % 2 > 0)
                                {
                                    y += 1;
                                }

                                break;
                            }
                        case ContentAlignment.BottomLeft:
                            {
                                x = 0;
                                y = this.Height - h;

                                if ((this.Height - h) % 2 > 0)
                                {
                                    y += 1;
                                }

                                break;
                            }
                        case ContentAlignment.BottomCenter:
                            {
                                x = (this.Width - w) / 2;
                                y = this.Height - h;

                                if ((this.Width - w) % 2 > 0)
                                {
                                    x += 1;
                                }

                                break;
                            }
                        case ContentAlignment.BottomRight:
                            {
                                x = this.Width - w;
                                y = this.Height - h;

                                break;
                            }
                    }

                    if (_FillSplitHeight && h < this.Height)
                    {
                        h = this.Height;
                    }

                    if (x > 0)
                    {
                        x -= 1;
                    }
                    if (y > 0)
                    {
                        y -= 1;
                    }

                    return new Rectangle(x, y, w, h);
                }

            return Rectangle.Empty;
        }

        private Image GetImage(String imageName)
        {
            if (this.ImageList != null && this.ImageList.Images.ContainsKey(imageName))
            {
                return this.ImageList.Images[imageName];
            }

            return null;
        }

        #endregion

        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }

        #endregion
    }
}
bubuko.com,布布扣

 

[转]下拉按钮 C#_Winform 自定义控件,布布扣,bubuko.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!