Click here to Skip to main content
15,896,727 members
Articles / Programming Languages / C#

ReadOnly ComboBox

Rate me:
Please Sign up or sign in to vote.
3.00/5 (14 votes)
23 Oct 2008CPOL1 min read 91.7K   1.4K   30  
An extended ComboBox that adds a ReadOnly property to it.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing;

public class ExComboBox : ComboBox
{
    private bool m_Unselectable = false;
    DblPanel pnl = new DblPanel();
    private const int WM_MOUSEWHEEL = 256;
    private const int WM_LBUTTONDOWN = 0x201;
    private const int WM_LBUTTONDBLCLK = 0x0203;
    private const int VK_SHIFT = 0x10;

    public ExComboBox()
    {
        pnl.Width = 17;
        pnl.Height = this.Height - 2;
        pnl.Left = this.Width - 18;
        pnl.Top = 1;
        this.Controls.Add(pnl);
        pnl.BringToFront();
        pnl.Visible = false;
    }

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        if (m_Unselectable == true)
            e.Handled = true;
        else
            base.OnKeyPress(e);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (m_Unselectable == true)
        {
            if ((int)e.KeyData == 131139)
                if (this.SelectedText != null)
                    Clipboard.SetText(this.SelectedText);
            e.Handled = true;
        }
        else
            base.OnKeyDown(e);
    }

    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        pnl.Left = this.Width - 18;
    }

    public bool ReadOnly
    {
        get
        {
            return m_Unselectable;
        }
        set
        {
            m_Unselectable = value;
            MakeUnselectable(m_Unselectable);
        }
    }

    private void MakeUnselectable(bool Unselectable)
    {
        if (m_Unselectable == true && this.DropDownStyle != ComboBoxStyle.Simple)
        {
            pnl.Visible = true;
        }
        else
        {
            pnl.Visible = false;
        }
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (m_Unselectable == true)
        {
            if (this.DropDownStyle == ComboBoxStyle.DropDownList)
            {
                if (keyData != Keys.Tab)
                    return true;
            }
            else
            {
                if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.PageUp || keyData == Keys.PageDown)
                    return true;
            }
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
    }

    protected override void WndProc(ref Message m)
    {
        if (this.m_Unselectable == true)
        {
            if (m.Msg == WM_MOUSEWHEEL || m.Msg == WM_LBUTTONDBLCLK)
                return;
            if (m.Msg == WM_LBUTTONDOWN)
            {
                this.Focus();
                return;
            }
        }

        base.WndProc(ref m);
    }

    protected override void OnDropDownStyleChanged(EventArgs e)
    {
        if (this.DropDownStyle == ComboBoxStyle.Simple)
            pnl.Visible = false;
        else
            if (m_Unselectable == true)
                pnl.Visible = true;
            else
                pnl.Visible = false;

        base.OnDropDownStyleChanged(e);
    }

    protected class DblPanel : Panel
    {
        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.Visible == true)
            {
                ComboBoxRenderer.DrawDropDownButton(e.Graphics, e.ClipRectangle, System.Windows.Forms.VisualStyles.ComboBoxState.Disabled);
                /*Pen pen = new Pen(Color.DarkGray);
                Pen penBR = new Pen(Color.LightGray);
                Pen penArrow = new Pen(Color.LightGray);
                penArrow.Width = 2;
                penArrow.EndCap = LineCap.Square;

                Graphics g = e.Graphics;
                LinearGradientBrush lgb = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height + 1), Color.LightGray, Color.Gray);
                g.FillRectangle(lgb, new Rectangle(new Point(0, 0), this.Size));
                g.DrawLine(penBR, new Point(0, 0), new Point(this.Width - 1, 0));
                g.DrawLine(penBR, new Point(this.Width - 1, 0), new Point(this.Width - 1, this.Height - 1));
                g.DrawLine(penBR, new Point(0, this.Height - 1), new Point(this.Width - 1, this.Height - 1));
                g.DrawLine(penBR, new Point(0, 0), new Point(0, this.Height - 1));
                g.DrawLine(pen, new Point(1, 0), new Point(this.Width - 2, 0));
                g.DrawLine(pen, new Point(this.Width - 1, 1), new Point(this.Width - 1, this.Height - 2));
                g.DrawLine(pen, new Point(1, this.Height - 1), new Point(this.Width - 2, this.Height - 1));
                g.DrawLine(pen, new Point(0, 1), new Point(0, this.Height - 2));

                g.DrawLine(penArrow, new Point(4, 7), new Point(8, 11));
                g.DrawLine(penArrow, new Point(8, 11), new Point(11, 8));

                pen.Dispose();
                penBR.Dispose();
                penArrow.Dispose();
                g = null;
                lgb.Dispose();*/
            }
        }
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader 510.Ventures
Netherlands Netherlands
Fábio is a programmer since 14 years, which start with his curiosity in games and how to make them.

After that his taste for programming only grew, at the age of 16 Fábio accidentaly stumbled in a program that makes programs, a.k.a. Visual Basic 5.
From there he self taught, through books, how to code in VB 5, 6 and later C, C++ and finally C#.

Currently Fábio specializes in C# Desktop and Web Development, that he's been working with since 2004. When he has time, he helps users on MSDN forums and tries to write articles on codeproject.

MSDN Profile: http://social.msdn.microsoft.com/profile/f%C3%A1bio%20franco/?type=forum

Comments and Discussions