Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#
Article

Custom ComboBoxes with Advanced Drop-down Features

Rate me:
Please Sign up or sign in to vote.
4.95/5 (55 votes)
22 Apr 2003CPOL4 min read 312.7K   12K   125   60
Contains several ComboBoxes which uses Windows themes and contains ComboBoxes with CheckBoxed lists and TreeViews

Preview of cutom comboboxes

CheckComboBox control
DateComboBox control

Introduction

During development of Windows Forms application I found that .NET controls do not satisfy me. After two days and many bug fixes I made satisfactory controls. I think this can help someone else. My controls sometimes use UtilityLibrary written by Carlos H. Perez. Thanks to him for good job ( sometimes some bugs are found, but this library give to me a good example how to create my own controls).

Code Bases

For a base control I use the System.Windows.Forms.Control class. For a child control I use the TextBox control. It is used by Combo only in cases when user sets the control in edit mode. The code structure is simple enougth and is used by me for all controls. All properties are made by the same template:

C#
// pseudo code
public datatype PropertyName
{
  get
  {
    return internalVariable;
  }
  set
  {
    if( value != internalVariable )
    {
      internalVariable = value;
      On<PropertyName>Changed();
    }
  }
}

As you can see, properties always have in internal variables which are used by me sometimes as a cache for user data. The main thing in property implementation of the control is that I always check if it is a new value, or rather different from old one. In many cases this can help us to stop event raising recursion.
Second thing in implementation is that after setting the new value I always call On<PropertyName>Changed();. In such methods I always implement logic of control and check how control must invalidate itself.

C#
// pseudo code
protected virtual void On<PropertyName>Changed()
{
   // ... business logic of control ...

   Raise<PropertyName>ChangedEvent();
}

// event raiser
private void Raise<PropertyName>ChangedEvent()
{
  if( <PropertyName>Changed != null )
  {
    <PropertyName>Changed( this, EventArgs.Empty );
  }
}

Why do I always raise events when the value of property changed? After reading on the .NET 247 site many articles about databinding features of .NET controls, I made a decision to always implement Property Change events. They help a lot when you try to use databinding in application and give developers good flexibility in the implementation of any control's logic. Databinding them can take too much time and will not be discussed in this article.

As you can see my controls always use such templatse to implement property logic.

Code

All combos are inherited from the base class CustomCombo which is implemented in the UtilityLibrary\Combos\CustomComboBox.cs file. The base class is abstract and all inheritors must implement such methods:

C#
protected abstract void OnPrevScrollItems();
protected abstract void OnNextScrollItems();
protected abstract void OnDropDownControlBinding( EventArgsBindDropDownControl e );
protected abstract void OnValueChanged();

Description:
OnPrevScrollItems - say control to change value of combo to previous.
OnNextScrollItems - say control to change value of combo to next one.
OnDropDownControlBinding - Special method which used by inheritors to attach own dropdown control to combo. OnValueChanged() - method used to check an correct value of combo. This method called by Value property code.

Also control has some additional methods which can be overrided by inheritors:

C#
protected virtual bool OnValueValidate( string value );
protected virtual void OnDropDownSizeChanged();
protected virtual void OnDropDownFormLocation();

Description:
OnValueValidate - method make validation of incoming values.
OnDropDownSizeChanged - method calculate size of dropdown form.
OnDropDownFormLocation - method calculate where dropdown form must be shown.

Also the abstract class has some helper methods which can be used by the user to boost combo fill.

C#
public void BeginUpdate();
public void EndUpdate();

Description:
BeginUpdate - control skip all invalidation code in class
EndUpdate - control start to invalidate itself after changes

How to Implement Your Own ComboBox

First step

Combobox is designed to support two modes: readonly and editable. In readonly mode the control does its own drawing of data and in editable mode all data drawing makes an internal TextBox control. The state of the control can be controled by the Readonly property.

So first of all select which type of combo you want to implement. I always try to implement both states of control.

Second step

The second step of implementatin is to select which control must be used in the drop down form. For that purposes class use OnDropDownControlBinding abstract method.

C#
protected override void OnDropDownControlBinding( CustomCombo.EventArgsBindDropDownControl e )
{
  e.BindedControl = m_tree; // m_tree is a TreeView control
  m_tree.ImageList = m_imgList;
  RaiseFillTreeByData( e );

  // in case when we do data load on scroll message then
  m_ctrlBinded = m_tree;
  m_bControlBinded = true;
}

Third step

The third step of implementation is optional and can be skipped. It's needed only when you want to make your own custom drawing of the combo value.

C#
protected virtual void OnItemSizeCalculate( object sender, CustomCombo.EventArgsEditCustomSize e )
{
  if( m_imgList != null )
  {
    int iWidth = m_imgList.ImageSize.Width + 2;
    e.xPos  += iWidth;
    e.Width -= iWidth;
  }
}

protected override void OnPaintCustomData(System.Windows.Forms.PaintEventArgs pevent)
{
  Graphics g = pevent.Graphics;
  Rectangle rc = pevent.ClipRectangle;

  if( m_tree.SelectedNode != null && m_imgList != null )
  {
    Rectangle rcOut = new Rectangle( rc.X + 2, rc.Y+2, m_imgList.ImageSize.Width, rc.Height - 4 );
    int index = m_tree.SelectedNode.ImageIndex;

    if( m_imgList.Images.Count > index && m_imgList.Images.Count > 0 )
    {
      if( index < 0 ) index = 0;
      Image img = m_imgList.Images[ index ];
      g.DrawImage( img, rcOut );
    }
  }
}

The first method calculates the area in which the developer wants to draw and what does not. The second method is a paint method. CustomCombo give you a chance to override and implement your own drawing for all items of the control. The paint method can logically be split into background drawing methods and item drawing. In most cases background drawing is no needed to override, but you can do that.

Data flow

When a user types any text in combo then we first check is data old or new, then we validate the value by calling the OnValueValidate method, and if it return true then call the OnValueChanged method.

Some features

In my implementation of the controls I use following techniques: data loading on user demand... This feature you can find in the TreeCombo class implementation.

Known Bugs or Not Yet Implemented Features

In Readonly mode not all keybord functions work. (Up/Down arrows do not work).

License

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


Written By
CEO ArtfulBits Inc.
Ukraine Ukraine
Name:Kucherenko Oleksandr

Born:September 20, 1979

Platforms: Win32, Linux; - well known and MS-DOS; Win16; OS/2 - old time not touched;

Hardware: IBM PC

Programming Languages: Assembler (for Intel 80386); Borland C/C++; Borland Pascal; Object Pascal; Borland C++Builder; Delphi; Perl; Java; Visual C++; Visual J++; UML; XML/XSL; C#; VB.NET; T-SQL; PL/SQL; and etc.

Development Environments: MS Visual Studio 2001-2008; MS Visual C++; Borland Delphi; Borland C++Builder; C/C++ any; Rational Rose; GDPro; Together and etc.

Libraries: STL, ATL, WTL, MFC, NuMega Driver Works, VCL; .NET 1.0, 1.1, 2.0, 3.5; and etc.

Technologies: Client/Server; COM; DirectX; DirectX Media; BDE; HTML/DHTML; ActiveX; Java Servlets; DCOM; COM+; ADO; CORBA; .NET; Windows Forms; GDI/GDI+; and etc.

Application Skills: Databases - design and maintain, support, programming; GUI Design; System Programming, Security; Business Software Development. Win/Web Services development and etc.

Comments and Discussions

 
QuestionJust a basic question. How can I fill this checkCombo with an IList? Pin
Aleks Almeida12-Aug-13 12:32
Aleks Almeida12-Aug-13 12:32 
Question.NET 4.0 Pin
moep12321-Nov-12 8:51
moep12321-Nov-12 8:51 
AnswerRe: .NET 4.0 Pin
m.elabbady29-Mar-14 5:28
m.elabbady29-Mar-14 5:28 
QuestionThank you!!!! Pin
reixuemin20-Oct-11 15:29
reixuemin20-Oct-11 15:29 
GeneralCheckBoxes With Nodes Pin
Farid_Bilal26-Feb-09 20:15
Farid_Bilal26-Feb-09 20:15 
QuestionCan you help me in ASP.Net,please. Pin
love_big_cat2-Apr-08 16:20
love_big_cat2-Apr-08 16:20 
QuestionHow refresh the combo items in RunTime? [modified] Pin
Jhon Williams Munoz14-Sep-07 8:44
Jhon Williams Munoz14-Sep-07 8:44 
QuestionRightToLeft? Pin
perspolis21-May-07 5:14
perspolis21-May-07 5:14 
QuestionUnder XP - how to remove horizontal scrollbar Pin
Vegemite12-Oct-06 9:31
Vegemite12-Oct-06 9:31 
GeneralExpand automatically Pin
sylvainOz5-Jun-06 20:24
sylvainOz5-Jun-06 20:24 
GeneralTurning Checkcombo into normal combo Pin
krismadair17-May-06 22:52
krismadair17-May-06 22:52 
GeneralSuggestion Pin
rncwnd5-May-06 4:27
rncwnd5-May-06 4:27 
GeneralQuestion regarding combo boxes. Pin
na.nu5-May-06 0:37
na.nu5-May-06 0:37 
AnswerRe: Question regarding combo boxes. Pin
Oleksandr Kucherenko5-May-06 1:12
Oleksandr Kucherenko5-May-06 1:12 
GeneralSorted Nodes??ß Pin
langdar113-Feb-06 4:06
langdar113-Feb-06 4:06 
AnswerRe: Sorted Nodes??ß Pin
Oleksandr Kucherenko17-May-06 5:04
Oleksandr Kucherenko17-May-06 5:04 
GeneralRe: Sorted Nodes??ß Pin
hamed Rezaei _6-Mar-09 23:49
hamed Rezaei _6-Mar-09 23:49 
GeneralThe dateTime combo box has error in Chinese systems Pin
Yefu Wang2-Feb-06 16:48
Yefu Wang2-Feb-06 16:48 
General&quot;Deletable&quot; but not can not &quot;Write&quot; Pin
sabankocal2-Jun-05 20:58
sabankocal2-Jun-05 20:58 
GeneralDefault Xp Style View Pin
sabankocal1-Jun-05 22:44
sabankocal1-Jun-05 22:44 
GeneralRe: Default Xp Style View Pin
Oleksandr Kucherenko2-Jun-05 0:16
Oleksandr Kucherenko2-Jun-05 0:16 
GeneralRe: Default Xp Style View Pin
SkaterGirl7-Jun-06 6:29
SkaterGirl7-Jun-06 6:29 
AnswerRe: Default Xp Style View Pin
Oleksandr Kucherenko7-Jun-06 21:30
Oleksandr Kucherenko7-Jun-06 21:30 
Generalusing buttons to go up and down and select items in combo box with checkboxes Pin
Anonymous9-Feb-05 4:57
Anonymous9-Feb-05 4:57 
General!!! new version of control !!! Pin
Oleksandr Kucherenko5-Jan-04 23:13
Oleksandr Kucherenko5-Jan-04 23:13 

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.