Click here to Skip to main content
13,664,248 members
Click here to Skip to main content
Add your own
alternative version


104 bookmarked
Posted 10 Feb 2007
Licenced Public Domain


, 11 Feb 2007
Rate this:
Please Sign up or sign in to vote.
A template for custom ComboBoxes


Controls like the MultiColumnCombo, the TreeCombo, the better DateTimePicker or similar can be found in all sorts of implementations on almost every programming site. All of these implementations have their pros and cons, so it can be very hard to choose the best for your purpose and it gets even harder as soon as you have to mix them in your particular application. Since they tend to be designed in a slightly different way, it could well happen that you end up with an application where each of those specialized ComboBoxes has its own custom behavior. This can make your application quite irrational for your users to work with.

That's why in my daily work the requirement arose to build something like a library or template as basis for custom combos. There might be bugs in it, at least in the early versions, there might be better solutions around for some particular combo behavior, but all combos created from that template will at least have consistent base behavior. New features as well as bug fixes will have to be implemented only once.


Writing a decent ComboBox clone is not all that sophisticated, but can become complex enough once you start to take the details into account. Displaying a modal form instead of the drop-down area is fairly easy, but having the hosting form appear focused requires some extra care. Fortunately someone a lot cleverer than I, Steve McMahon, the guy who runs, already published a decent solution on popup windows in .NET, so that all I needed to do was to take his excellent work and just add a little bit of my own code. Because I needed to make Steve's code fit into a larger application infrastructure, I had to refactor the original class names, but appart from that Steve's code was left next to unchanged.

Using the code

DropDownPanel is a simple UserControl hosting a ComboBox and exposing the interface IDropDownAware and a single property DropDownControl, that again is of type IDropDownAware. To enable any control to show up in the drop-down area of the DropDownPanel all you have to do is implement 2 interfaces (one for the control itself and one for the value it exposes) and set the DropDownPanel's DropDownControl to an instance of it.

The DropDownPanel then takes care to host your control in its internal DropDownForm, that pops up instead of the drop-down area of its ComboBox whenever the combo's DropDown event is triggered. Firing the FinishEditing event from your control or a mouse click outside the DropDownForm will cause the DropDownForm to close and subsequently the DropDownPanel to fire its own FinishEditing event to let your application decide the next steps.


This interface enables the DropDownPanel to expose its value and provides 2 events, one that indicates that the user is done with the dropdown control and one that indicates changes while editing is in process. Possibly the custom EventArgs will be extended in future versions as the necessity arises.

public interface IDropDownAware
    event DropDownValueChangedEventHandler FinishEditing;
    event DropDownValueChangedEventHandler ValueChanged;
    object Value { get; set; }

So let's start creating a very basic implementation of a DropDownTree as can be seen in this article's screenshot. We derive a class from TreeView and implement IDropDownAware. Of course some events have to be handled to inform the DropDownPanel when we think the user has choosen a TreeNode or canceled editing.

internal class DropDownTree : TreeView, IDropDownAware
    public DropDownTree()

    protected override void OnAfterSelect(
        TreeViewEventArgs e)
        if (ValueChanged != null)
            ValueChanged(this, new 
    protected override void OnDoubleClick(EventArgs e)
        TreeNode node = HitTest(PointToClient(Cursor
        if (FinishEditing != null)
        FinishEditing(this, new 

    protected override void OnKeyUp(KeyEventArgs e)
        if (FinishEditing != null)
            switch (e.KeyCode)
                case Keys.Enter:
                    FinishEditing(this, new 
                case Keys.Escape:
                    FinishEditing(this, new 
    // IDropDownAware Implementation
    public event DropDownValueChangedEventHandler FinishEditing;
    public event DropDownValueChangedEventHandler ValueChanged;

    public object Value
        get { return base.SelectedNode; }
            if (value is TreeNode)
                base.SelectedNode = value as TreeNode; 


Since I like the new object databinding features in .NET 2.0, I use them extensively throughout my projects. So I had this interface already available in my little toolbox, which is why I decided to reuse it here as well.

To keep the control as simple as possible I set the internal combo's DropDownStyle to DropDownList to prevent text editing in the ComboBox itself and instead allow editing in the drop-down portion of the control only. When DropDownPanel's value should change after editing your control (ie. your control fires the FinishEditing event), the combo's DataSource has to be cleared and the new value added to the combo's DataSource in order to display the new value.

Possibly in future versions of this control text editing features will be added, which could then make this simple interface obsolete. Don't get excited, I am afraid that whatever will replace it will be a lot more complex.

public interface ILookupItem<T> where T: struct
    T      Id   { get; }
    string Text { get; }

We better not populate the DropDownTree with standard TreeNodes but with objects derived from it instead. We just add an implementation of our ILookupItem<T>:

internal class DropDownNode : TreeNode, ILookupItem<long>
    public DropDownNode() : base()
    public DropDownNode(string Text) : base(Text)
    public DropDownNode(string Text, DropDownNode[] 
        Children) : base(Text, Children)
    public DropDownNode(string Text, int ImageIndex, int 
                                    : base(Text, ImageIndex,
    public DropDownNode(string Text, int ImageIndex, 
                        int SelectedImageIndex, 
                        DropDownNode[] Children) 
                        : base(Text, ImageIndex, 
                            SelectedImageIndex, Children)

    // ILookupItem<long> Implementation
    public long Id
        get { return 0; }
    public new string Text
        get { return base.Text; }

Having done this, all that is left to do, is to set up the DropDownTree and to push it into the DropDownPanel from within our application:

protected override void OnLoad(EventArgs e)
    treePanel.DropDownControl = CreateTree(); 

private DropDownTree CreateTree()
    DropDownTree tree = new DropDownTree();
    DropDownNode root = new DropDownNode("1");
    tree.BorderStyle = BorderStyle.None;
    tree.Size = new Size(200, 300);
    for (int i = 1;  i <= 20; i++)
        DropDownNode node = new DropDownNode("1." + 
        for (int j =  1;  j <= 2; j++)
            node.Nodes.Add(new DropDownNode("1." + 
                i.ToString("00") + "." + j.ToString()));
    this.treePanel.FinishEditing += new 
    this.treePanel.ValueChanged += new 
    return tree;

Of course it would be better to inherit your own specialized combos from DropDownPanel, instead of using the DropDownPanel itself. A sample for such an inherited control is included in the Demo project.


  • 1.0 Initial Release


This article, along with any associated source code and files, is licensed under A Public Domain dedication


About the Author

Alexander Stojakovic
Technical Lead Artaker Computersysteme GmbH
Austria Austria
No Biography provided

You may also be interested in...

Comments and Discussions

Questionissue when combo is inside a tab [modified] Pin
juan.carlos25-Mar-10 8:42
memberjuan.carlos25-Mar-10 8:42 
QuestionRe: issue when combo is inside a tab Pin
blah23810-Aug-10 7:18
memberblah23810-Aug-10 7:18 
Questionno win32 api? Pin
Unruled Boy16-Apr-09 21:09
memberUnruled Boy16-Apr-09 21:09 
QuestionSingle click to select, cause the form deactivated Pin
iceway6-Nov-08 20:59
membericeway6-Nov-08 20:59 
AnswerRe: Single click to select, cause the form deactivated Pin
Alexander Stojakovic18-Nov-08 9:54
memberAlexander Stojakovic18-Nov-08 9:54 
GeneralRe: Single click to select, cause the form deactivated [modified] Pin
iceway1-Dec-08 21:07
membericeway1-Dec-08 21:07 
GeneralRe: Single click to select, cause the form deactivated Pin
Alexander Stojakovic3-Dec-08 11:56
memberAlexander Stojakovic3-Dec-08 11:56 
GeneralRe: Single click to select, cause the form deactivated Pin
iceway30-Dec-08 14:56
membericeway30-Dec-08 14:56 
GeneralGood article! I have question Pin
bluemoong12-Feb-08 23:11
memberbluemoong12-Feb-08 23:11 
QuestionIs it necessary to be a UserControl? Pin
Steve Harding2-Sep-07 14:33
memberSteve Harding2-Sep-07 14:33 
AnswerRe: Is it necessary to be a UserControl? Pin
Alexander Stojakovic2-Sep-07 22:46
memberAlexander Stojakovic2-Sep-07 22:46 
QuestionNice control, but I have a question Pin
vovair29-May-07 0:26
membervovair29-May-07 0:26 
AnswerRe: Nice control, but I have a question Pin
Alexander Stojakovic29-May-07 6:56
memberAlexander Stojakovic29-May-07 6:56 
GeneralRe: Nice control, but I have a question Pin
vovair29-May-07 22:17
membervovair29-May-07 22:17 
GeneralNodes.Find problem Pin
perspolis26-May-07 7:04
memberperspolis26-May-07 7:04 
GeneralRe: Nodes.Find problem Pin
Alexander Stojakovic29-May-07 6:35
memberAlexander Stojakovic29-May-07 6:35 
QuestionRightToLeft? Pin
perspolis21-May-07 5:39
memberperspolis21-May-07 5:39 
AnswerRe: RightToLeft? Pin
Alexander Stojakovic23-May-07 0:29
memberAlexander Stojakovic23-May-07 0:29 
QuestionShow value selected Pin
AldinCC2-May-07 4:09
memberAldinCC2-May-07 4:09 
AnswerRe: Show value selected Pin
Alexander Stojakovic9-May-07 3:48
memberAlexander Stojakovic9-May-07 3:48 
GeneralRe: Show value selected Pin
Aldin CC9-May-07 6:05
memberAldin CC9-May-07 6:05 
GeneralRe: Show value selected Pin
yongfa36511-May-09 0:29
memberyongfa36511-May-09 0:29 
GeneralPlease Tell me Pin
Member #386972714-Mar-07 21:48
memberMember #386972714-Mar-07 21:48 
GeneralRe: Please Tell me Pin
Alexander Stojakovic15-Mar-07 10:38
memberAlexander Stojakovic15-Mar-07 10:38 
GeneralUse ToolStripDropDown class Pin
Lukasz Swiatkowski13-Feb-07 4:21
memberLukasz Swiatkowski13-Feb-07 4:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.180810.1 | Last Updated 11 Feb 2007
Article Copyright 2007 by Alexander Stojakovic
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid