[WIN] Vista Style ComboBox

[WIN] Vista Style ComboBox

前言

在研究 ComboBoxRenderer 時,發現 ColoredComboBox ,看它是 Vista Style 蠻好看的,所以就整理成 VistaStyleComboBox ,同時跟大家分享研究!

以下為Windows 7看起來的樣子!

image

會有 VistaStyle 主要是檢查 OS 是否 Vista 以上的版本,是的話,就使用 ButtonRenderer.DrawButton ,不是的話,就用原本的方式繪出來!

另外,使用 ComboBoxRenderer 還要判斷是否有 Support 才可以使用哦! 完整的Code如下,

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
//modify from http://bytes.com/topic/c-sharp/answers/635882-inherit-combobox-windows-vista

 
public class VistaStyleComboBox : ComboBox
{
    #region Private Members
        private bool IsVista;
        private ComboBoxState cb_State = ComboBoxState.Normal;
    #endregion

    #region Constructor
        public VistaStyleComboBox()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            //判斷是否vista以上的pc
            IsVista = ((Environment.OSVersion.Version >= new Version("6.0.0")) && (Environment.OSVersion.Platform == PlatformID.Win32NT));
            this.DropDownStyle = ComboBoxStyle.DropDownList;
            this.FlatStyle = FlatStyle.System;
            this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
            this.DrawItem += new DrawItemEventHandler(VistaStyleComboBox_DrawItem);
        }
    #endregion


        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (Enabled == false)
                cb_State = ComboBoxState.Disabled;
            Rectangle r = e.ClipRectangle;
            if (IsVista)
            {
                PushButtonState pb_State = PushButtonState.Normal;
                if (cb_State == ComboBoxState.Disabled)
                    pb_State = PushButtonState.Disabled;
                else if (cb_State == ComboBoxState.Hot)
                    pb_State = PushButtonState.Hot;
                else if (cb_State == ComboBoxState.Pressed)
                    pb_State = PushButtonState.Pressed;
                
                ButtonRenderer.DrawButton(e.Graphics, r, pb_State);
                r = new Rectangle(r.Right -
                System.Windows.Forms.SystemInformation.VerticalScrollBarWidth + 2,
                e.ClipRectangle.Top,
                System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 4,
                e.ClipRectangle.Height);
                DrawArrow(e.Graphics, r);
            }
            else
            {
                r = new Rectangle(r.Right -
                System.Windows.Forms.SystemInformation.VerticalScrollBarWidth,
                e.ClipRectangle.Top,
                System.Windows.Forms.SystemInformation.VerticalScrollBarWidth,
                e.ClipRectangle.Height);
                if (ComboBoxRenderer.IsSupported)
                {
                    ComboBoxRenderer.DrawTextBox(e.Graphics, r, cb_State);
                    ComboBoxRenderer.DrawDropDownButton(e.Graphics, r,
                    cb_State);
                }
                else
                {
                    ComboBoxRenderer.DrawDropDownButton(e.Graphics, r,
                    cb_State);
                }
                
            }
            r = e.ClipRectangle;
            r.Inflate(0, -2);
            r.Offset(0, 1);
            DrawItemText(e.Graphics, r, SelectedIndex);
        }

        private void DrawArrow(Graphics g, Rectangle rect)
        {
            Point p1 = new Point(rect.X + 3, rect.Y + rect.Height / 2
            - 2);
            Point p2 = new Point(rect.X + rect.Width - 3, rect.Y +
            rect.Height / 2 - 2);
            Point p3 = new Point(rect.X + rect.Width / 2, rect.Y +
            rect.Height / 2 + 2);
            g.FillPolygon(new
            SolidBrush(System.Drawing.SystemColors.ControlText), new Point[]{p1,
        p2, p3});
        }
        private void DrawItemText(Graphics g, Rectangle r, int Index)
        {
            if (Index == -1 || Items.Count == 0)
                return;
            Color c = ForeColor;

            SolidBrush b = new SolidBrush(c);
            g.DrawString(Items[Index].ToString(), this.Font, b, r);
            b.Dispose();
        }

        protected void VistaStyleComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            DrawItemText(e.Graphics, e.Bounds, e.Index);
            e.DrawFocusRectangle();
        }

        #region Mouse Movement
        // Draw the smaller pressed button image.
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            cb_State = ComboBoxState.Pressed;
            Invalidate();
        }

        // Draw the button in the hot state.
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            cb_State = ComboBoxState.Hot;
            Invalidate();
        }

        // Draw the button in the unpressed state.
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            cb_State = ComboBoxState.Normal;
            Invalidate();
        }

        // Draw the button hot if the mouse is released on the button.
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            OnMouseEnter(e);
        }

        // Detect when the cursor leaves the button area while
        // it is pressed.
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Detect when the left mouse button is down and
            // the cursor has left the pressed button area.
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left &&
            !ClientRectangle.Contains(e.Location) &&
            cb_State == ComboBoxState.Pressed)
            {
                OnMouseLeave(e);
            }
        }

        #endregion
}
 

 

參考資料:

ColoredComboBox

範例程式:

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^