Click here to Skip to main content
11,932,168 members (62,318 online)
Click here to Skip to main content
Add your own
alternative version


49 bookmarked

ComboBox List Control Host

, 9 Jan 2009 CDDL
Rate this:
Please Sign up or sign in to vote.
An article demonstrating how to host list controls inside a standard ComboBox. Easily create your own CheckedList ComboBox and others.



This article allows you to create your own fully customized list controls for display in a combobox drop down style while at the same time staying with as much intrinsic/standard control functionality as is possible. The drop window behaviour supports multiple select operations without closing the drop window, and does not use a single API call. The base combobox implementation uses the ToolStripDropDown component to replace the built in drop window functionality of the base combobox along with a ToolStripControlHost component used internally to host a third control. The base implementation allows a developer to extend functionality by implementing a variety of different controls. Ideally, only use list controls such as the following.

  • ListBox
  • CheckedListBox
  • MonthCalendar
  • TreeView
  • DataGridView


The code for this article is the result of a request that came across my desk. My brief was to "give us a checked combobox like the one used in Team System". After some serious search engine abuse, I came up with nothing usable in any stable format that did exactly what I wanted. All the samples used API calls - badly at that too. I have a rule, when you need to use APIs calls... don't! So, I did the next best thing, and re-invented the wheel, which also led to my very first article which I've wanted to do for sometime now. Hats off to the prolific article writers out there - where you find the time, I couldn't even begin to fathom. Anyway, here goes.

Using the Code

Using the code is pretty straightforward. Within a Windows Forms application, we have Form1. The controls/base folders contain a base combobox implementation and a CheckedListComboBox implementation built on top of the base combobox implementation. Simply extract the source code to a folder near you, open it and build the project in VS 2008. Select the Items property to create a list and hit the Play button. For this version only, our control won't support data binding simply because the standard Windows CheckedListBox control doesn't support data binding - I will address this functionality in my next article.

Base Implementation

Choice of Container

Firstly, we must hide the base drop window size to appear invisible, then prepare our internal containers that are going to provide the necessary functionality, specifically:

  • 01 x standard ToolStripDropDown component, which is a marvelous little component that provides a host of functionality as ‘standard’. One particularly useful tasty morsel is that the behavior allows mouse click functionality to select listed items while at the same time maintaining an open drop list for subsequent select operations. Something that can only be properly achieved in C++. The sample code/articles I found all used API calls – which, besides being unstable, is an attempt to access the root C++ functionality anyway.
  • 01 x standard ToolStripControlHost, almost a Swiss army knife when it comes to its flexibility in wrapping any other control, and ease of use with almost no code required.
namespace CheckedComboTest.Controls.Base
    public abstract class ComboBoxEx : ComboBox

        #region Declarations & Constructors

        private ToolStripDropDown tsdd = new ToolStripDropDown();
        private ToolStripControlHost tsch = null;

        private int dropDownHeight;

        new public event EventHandler DropDown;
        new public event EventHandler DropDownClosed;

        public ComboBoxEx()
            : base()
            base.DropDownHeight = 1;



Always important in any component design is the manner and timing of any internal container instantiation. That’s why I like to use the base OnHandleCreated method to build the internals because by the time the thread executes my code, I know the base control has been instantiated and my control instance has a handle attached to it.

#region Base Overrides/Overloads

protected override void OnHandleCreated(EventArgs e)
    //  our handle has now been officially created; build internals


Internally, we configure our drop container and call the abstract OnCreateHost() method, forcing any implementation up the hierarchy to provide a control for hosting at the same time as the creation of the host container is taking place.

//  call extended implementations to provide a guest control
tsch = new ToolStripControlHost(OnCreateHost());

All we need to do is provide our own drop height functionality, and we can proceed with a custom implementation of ComboBoxEx.

Custom Implementation

Our custom implementation needs a class that inherits from our ComboBoxEx base component, and for our example, let’s use a CheckedListBox control.

public class CheckedListComboBox : Base.ComboBoxEx

    #region Declarations & Constructors

    private CheckedListBox checkedListBox = new CheckedListBox();

    public CheckedListComboBox()
        : base()


Actually, all our implementation needs to do is return an instance of a list control back through the OnCreateHost() function, like this…

#region Base Overrides/Overloads

protected override Control OnCreateHost()
    return checkedListBox;

…and then we can paste from the toolbox onto the form and run the project. The resulting drop window is quite normal at first site, especially when compared with the standard ComboBox, till we actually click to display the drop windows. Our custom drop window has a drop shadow effect along with matching border colors, and all this as provided standard by Microsoft.

Lastly, replace the standard Items property with the one exposed by the CheckedListBox control et voila:

    System.Design, Version=, Culture=neutral,
    PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
new public CheckedListBox.ObjectCollection Items
        return checkedListBox.Items;

Points of Interest

Effectively, the only thing created was an intermediate layer of code allowing multiple components to be plugged into each other. We didn’t even have to ‘hack’ any drawing routine or use even a single API call. The available controls are simple building blocks, and while it is great fun to twist and 'hack' something to death, it is easy to overdo, especially when done without a clear idea of how to extend the framework.

In my next article, I will expand on my custom implementations to cover data binding on custom implementations.


First release!


This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


About the Author

Software Developer (Senior) Motla utilities
South Africa South Africa
Have been coding for the last 10 years - vb(sucks), c#, ms sql, web services, web + mobile(jquery, html5, css3 etc!), windows embedded, mobile + windows azure. Really enjoy abstraction and implementing coding patterns, with some customized component development thrown in for good measure. Have experience in ERP, Medical Practice Management, Laboratory Stats/Calibration, Insurance Underwriting and Utilities Management. Also done quite a bit of re-design & developing of legacy apps from as far back as VB3 (before my time even) through VB6(interop). Really dig the MS tech stack especially what they did with Azure supporting all the open source stuff.

You may also be interested in...

Comments and Discussions

GeneralZip file is damaged Pin
Ap079-Jan-09 11:03
memberAp079-Jan-09 11:03 
GeneralRe: Zip file is damaged Pin
zaphnath11-Jan-09 19:20
memberzaphnath11-Jan-09 19:20 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.151126.1 | Last Updated 9 Jan 2009
Article Copyright 2009 by wmerifield
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid