Click here to Skip to main content
11,706,007 members (54,661 online)
Click here to Skip to main content

CheckBox ComboBox Extending the ComboBox Class and Its Items

, 29 Apr 2008 CPOL 502.6K 29.7K 205
Rate this:
Please Sign up or sign in to vote.
An article on a CheckBox ComboBox control which extends the ComboBox.Items.
Screenshot - CheckBoxComboBox.jpg

Introduction

I needed a way to minimise the space required by a Filter control, yet maximise the filter capabilities provided to the user. One way to accomplish this was to replace a Grouped Box of CheckBox controls with a CheckBoxComboBox control. There are several CheckBoxComboBox controls on the web, but all of the ones I found and tested had something missing.

Some controls simulated a check box by only painting it in the Popup, which means the Checkbox did not behave like a Checkbox should and it caused the Popup to close before the user could make more selections. Other controls did not specialise a normal ComboBox, so you lost the existing functionality of a ComboBox control and its Items, for example, you could not bind the control to a custom DataSource anymore.

This CheckBoxComboBox combines the standard .NET ComboBox with real CheckBoxes and accomplishes this task by creating a wrapper for the ComboBox.Items (it does not use a CheckBoxListBox either). Another point worth mentioning here, is that it also uses the neat PopUp solution provided by Lukasz Swiatkowski which you can find here. This solved some custom PopUp problems like focus removed from the owner form, resize capabilities, positioning, etc. Really worth looking at.

Background

The CheckBoxComboBox provides a CheckBoxItems property which contains the CheckBoxes shown in the list, as well as a link to the ComboBox Item object it links to. In addition, it has a CheckBoxCheckedChanged event which bubbles the CheckedChanged events of the CheckBox items back to the ComboBox.

Using the Code

Using the code is simple, you can populate the ComboBox like you would do normally, by either populating the Items manually or linking to a DataSource.

However, make sure you think about the following, especially if you are going to be binding to the control. You might currently have a list of objects which you want to list in the CheckBoxComboBox popup for the user to make a selection. That selection requires a bool property which when binded will be set back to the binded object. Does that object really care whether it is selected somewhere? What would happen if you not only wanted to select the object, but also wanted to add additional display information, such as how many of those objects are available? All this extra information can clutter your object unnecessarily. So, I included an additional class which you can use to solve this for you. It basically takes your list of objects, and adds a Selection and Count property for you to manipulate without adding those properties to your existing object where it is actually not relevant. You can then easily extend on these properties or change their behavior without affecting your current class. (It's separate and clean.) The code below demonstrates its use with a custom List<T> and a DataTable, but the only requirement is an IEnumerable type.

#region POPULATE THE "MANUAL" COMBO BOX

cmbManual.Items.Add("Item 1");
cmbManual.Items.Add("Item 2");
cmbManual.Items.Add("Item 3");
cmbManual.Items.Add("Item 4");
cmbManual.Items.Add("Item 5");
cmbManual.Items.Add("Item 6");
cmbManual.Items.Add("Item 7");
cmbManual.Items.Add("Item 8");

#endregion

The code sample above is straightforward, eight string objects are added to the ComboBox as you would do normally.

#region POPULATED USING A CUSTOM "IList" DATASOURCE

_StatusList = new StatusList();

_StatusList.Add(new Status(1, "New"));
_StatusList.Add(new Status(2, "Loaded"));
_StatusList.Add(new Status(3, "Inserted"));
_StatusList.Add(new Status(4, "Updated"));
_StatusList.Add(new Status(5, "Deleted"));

cmbIListDataSource.DataSource = 
    new ListSelectionWrapper<status />(_StatusList);
cmbIListDataSource.ValueMember = "Selected";
cmbIListDataSource.DisplayMemberSingleItem = "Name";
cmbIListDataSource.DisplayMember = "NameConcatenated";

#endregion

In this extract, a List<Status> object is binded to the list. Note that it is not binded directly, I used the ListSelectionWrapper<T> to handle the selection for me, because I did not want to modify my existing "re-usable" Status class.

#region POPULATED USING A DATATABLE

DataTable DT = new DataTable("TEST TABLE FOR DEMO PURPOSES");
DT.Columns.AddRange(
new DataColumn[]
    {
        new DataColumn("Id", typeof(int)),
        new DataColumn("SomePropertyOrColumnName", typeof(string)),
        new DataColumn("Description", typeof(string)),
    });
DT.Rows.Add(1, "AAAA", "AAAAA");
DT.Rows.Add(2, "BBBB", "BBBBB");
DT.Rows.Add(3, "CCCC", "CCCCC");
DT.Rows.Add(3, "DDDD", "DDDDD");

cmbDataTableDataSource.DataSource =
    new ListSelectionWrapper<DataRow>(
    DT.Rows,
    // "SomePropertyOrColumnName" will populate the Name 
    // on ObjectSelectionWrapper.
    "SomePropertyOrColumnName" 
    );
cmbDataTableDataSource.DisplayMemberSingleItem = "Name";
cmbDataTableDataSource.DisplayMember = "NameConcatenated";
cmbDataTableDataSource.ValueMember = "Selected";

#endregion

In the third example, I also use the ListSelectionWrapper<T>, because my table does not have a Selection column. Note however, that I don't wrap the DataTable, I wrap the Rows instead, which is IEnumerable. When initialising the wrapper, I specify "SomePropertyOrColumnName", because the wrapper uses ToString() on the objects, which normally on a DataRow will result in "System.Data.DataRow" instead of the real text you would want to display. You can use this Property specifier to indicate a PropertyDescriptor or normal property on objects other than a DataRow if you did not want them to use ToString() either. This can be useful.

If you want to know which items are selected, you have two options:

  1. Use the CheckBoxItems property on the ComboBox which is a list of items wrapping each item in the ComboBox.Items list. The CheckBoxComboBoxItem class is a standard CheckBox, and therefore the bool value you are looking for is contained in Checked.
  2. Or if you stored a reference to the ListSelectionWrapper<T>, you could use that to access the Selected property of the binded list.
if (ComboBox.CheckBoxItems[5].Checked)
    DoSomething();

OR

if (StatusSelections.FindObjectWithItem(UpdatedStatus).Selected)
    DoSomething();

If a CheckBoxComboBox does not make sense or seem necessary to you, consider the following filter as a real-world example.

The ComboBox shown here, replaces a Group Box shown below it.

Screenshot - CheckBoxComboBox_2_small.jpg

There is no space for this control:

Screenshot - CheckBoxComboBox_3.jpg

Points of Interest

I was originally a religious Delphi developer, so working with this control has taught me a lot about C# and .NET. The ComboBox has always been, and still is a difficult control to customise, and doing so can prove to take up more hours of your time than you anticipated.

The following list of sources may help your attempts, and also contains links to other CheckBox ComboBox controls:

  1. Simple Pop-up Control
  2. Custom ComboBoxes with Advanced Drop-down Features
  3. An OwnerDraw ComboBox with CheckBoxes in the Drop-Down

History

2007-11-06

  • Changed the pop-up frames and duration to zero to fix the black flicker. I couldn't figure a way to resolve it while keeping the fade effect.
  • Solved a problem where the selected state of the Checkbox has not yet been assigned back to the binded property before the CheckBoxCheckedChanged event is raised. I now assign this value back myself if the ComboBox uses a DataSource.
  • Added a class to wrap existing lists so I don't need to add unnecessary Selected properties in a class where it is not needed. This List wrapper does support IBindingList sources, so if you implement that interface in your list, this wrapper will keep itself in sync with your list automatically. But, it is not a requirement at all.
  • The Selection wrappers also help working with counts.
  • Changed the CheckBoxItems to synchronise when the property is accessed, so that Checked values can be initialised before the popup is shown.

2007-11-22

  • Added a sub property on the ComboBox called CheckBoxProperties which allows you to change the appearance of the Checkboxes, e.g. Flat, Text Alignment, etc.

License

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

Share

About the Author

Martin Lottering
Software Developer
South Africa South Africa
No Biography provided

You may also be interested in...

Comments and Discussions

 
Questionprevent resizing Pin
Member 118099462-Jul-15 20:53
memberMember 118099462-Jul-15 20:53 
QuestionDropDown and DropDownClosed Events Pin
nbl126812-Mar-15 20:39
membernbl126812-Mar-15 20:39 
GeneralGreat control - Thanks Pin
nbl126812-Mar-15 15:41
membernbl126812-Mar-15 15:41 
QuestionGrouping CheckboxItems with Title Pin
Member 112076564-Nov-14 21:55
memberMember 112076564-Nov-14 21:55 
Questionwhy i should click twice to selected Pin
ap03032923-Oct-14 23:46
memberap03032923-Oct-14 23:46 
AnswerRe: why i should click twice to selected Pin
Vincent DUVERNET (Nolmë Informatique)3-Dec-14 8:33
memberVincent DUVERNET (Nolmë Informatique)3-Dec-14 8:33 
AnswerRe: why i should click twice to selected Pin
Tino Fourie21-Mar-15 2:55
memberTino Fourie21-Mar-15 2:55 
AnswerRe: why i should click twice to selected Pin
Sakinha7-May-15 2:42
memberSakinha7-May-15 2:42 
GeneralRe: why i should click twice to selected Pin
Pablojz5-Jun-15 3:54
memberPablojz5-Jun-15 3:54 
Questionhow to add check all and uncheck alll function? Pin
Member 1116814220-Oct-14 16:33
memberMember 1116814220-Oct-14 16:33 
SuggestionFillcheckBoxComboBox && get SelectedValue of A special column in DataTable Pin
amir farashah16-Oct-14 23:18
memberamir farashah16-Oct-14 23:18 
QuestionSelectedValues Pin
amir farashah16-Oct-14 20:13
memberamir farashah16-Oct-14 20:13 
QuestionChange Font of DropDownControl Pin
Member 1062093511-Aug-14 22:21
memberMember 1062093511-Aug-14 22:21 
Questionhow to get the selected item value from combobox Pin
Mahatma Nishad21-Jul-14 7:59
memberMahatma Nishad21-Jul-14 7:59 
QuestionCorrections from the forum and DGV column Pin
sgissinger18-Apr-14 6:15
membersgissinger18-Apr-14 6:15 
QuestionHow to get the current index Pin
i Rajesh Kumar16-Apr-14 18:46
professionali Rajesh Kumar16-Apr-14 18:46 
QuestionEmpty list although several items declared Pin
Member 1062421216-Mar-14 3:15
memberMember 1062421216-Mar-14 3:15 
QuestionCannot get it to work in VB 2013 Pin
Member 106242126-Mar-14 22:23
memberMember 106242126-Mar-14 22:23 
QuestionHow To Get Selected Values Pin
podal19-Dec-13 16:07
memberpodal19-Dec-13 16:07 
AnswerRe: How To Get Selected Values Pin
HOASTONGE15-Jan-14 2:28
memberHOASTONGE15-Jan-14 2:28 
GeneralRe: How To Get Selected Values Pin
akhilrajau26-Jan-14 17:50
memberakhilrajau26-Jan-14 17:50 
GeneralRe: How To Get Selected Values Pin
sgissinger22-Apr-14 0:23
membersgissinger22-Apr-14 0:23 
QuestionHow to set tag proprty Pin
Sunil Bansode24-Oct-13 2:40
memberSunil Bansode24-Oct-13 2:40 
AnswerRe: How to set tag proprty Pin
Zipadie Doodah25-Mar-15 2:44
memberZipadie Doodah25-Mar-15 2:44 
GeneralMy vote of 5 Pin
Kenneth Salter13-Aug-13 7:29
professionalKenneth Salter13-Aug-13 7:29 
QuestionutStatusList Not Found Pin
Member 904274822-May-13 6:32
memberMember 904274822-May-13 6:32 
BugDoesn't work correctly Pin
Member 1000753323-Apr-13 3:36
memberMember 1000753323-Apr-13 3:36 
GeneralRe: Doesn't work correctly Pin
ByerRA13-May-13 12:26
memberByerRA13-May-13 12:26 
GeneralRe: Doesn't work correctly Pin
fSimon2110-Nov-13 23:48
memberfSimon2110-Nov-13 23:48 
QuestionHow to change the default height of the drop down checkbox list ?I need show more options defaultly. Pin
xuite love8-Apr-13 16:47
professionalxuite love8-Apr-13 16:47 
AnswerRe: How to change the default height of the drop down checkbox list ?I need show more options defaultly. Pin
Curros22-Apr-14 1:54
memberCurros22-Apr-14 1:54 
QuestionYou are a genius! Pin
Member 99721527-Apr-13 23:21
memberMember 99721527-Apr-13 23:21 
GeneralMy vote of 5 Pin
Zephyk20-Mar-13 1:35
memberZephyk20-Mar-13 1:35 
QuestionHow Can I Include this control in the DGV? I tried My Own. But failed! Pin
Manikandan Murugeshan29-Nov-12 21:05
memberManikandan Murugeshan29-Nov-12 21:05 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 10:50
mvpKanasz Robert27-Sep-12 10:50 
QuestionError when viewing Form in design mode Pin
murb6-Jul-12 19:09
membermurb6-Jul-12 19:09 
GeneralMy vote of 5 Pin
OriginalGriff8-Jun-12 1:13
mvpOriginalGriff8-Jun-12 1:13 
QuestionCreating a DataGridView Column of CheckBoxComboBox Cells Pin
Member 898602518-May-12 5:27
memberMember 898602518-May-12 5:27 
AnswerRe: Creating a DataGridView Column of CheckBoxComboBox Cells Pin
Sunil Bansode19-Jun-13 5:27
memberSunil Bansode19-Jun-13 5:27 
GeneralRe: Creating a DataGridView Column of CheckBoxComboBox Cells Pin
Zipadie Doodah25-Mar-15 2:46
memberZipadie Doodah25-Mar-15 2:46 
QuestionFails to display all the selected items Pin
shreyassv14-May-12 3:02
membershreyassv14-May-12 3:02 
QuestionNice One Pin
Anil B. Patil4-May-12 2:23
memberAnil B. Patil4-May-12 2:23 
QuestionCheckedComboboxEdit in devexpress winforms Pin
Suribabuk25-Apr-12 21:01
memberSuribabuk25-Apr-12 21:01 
QuestionMDIFormsManger is What controls Pin
Member 31716328-Apr-12 18:30
memberMember 31716328-Apr-12 18:30 
BugBroken with .NET 4.5 Pin
frostfiretulsa1-Apr-12 3:17
memberfrostfiretulsa1-Apr-12 3:17 
QuestionKeyboard selection of checkbox Pin
Ramanathan Govindasamy16-Dec-11 3:10
memberRamanathan Govindasamy16-Dec-11 3:10 
QuestionMy Vote Of 5 Pin
Tony Mamacos2-Nov-11 4:15
memberTony Mamacos2-Nov-11 4:15 
AnswerRe: My Vote Of 5 Pin
Paul Vassu24-Apr-12 1:56
memberPaul Vassu24-Apr-12 1:56 
GeneralRe: My Vote Of 5 Pin
Tony Mamacos24-Apr-12 2:43
memberTony Mamacos24-Apr-12 2:43 
Questionhow to set "select all" ? Pin
ahmadamiri30-Sep-11 4:07
memberahmadamiri30-Sep-11 4:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    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
Web04 | 2.8.150819.1 | Last Updated 29 Apr 2008
Article Copyright 2007 by Martin Lottering
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid