Click here to Skip to main content
Click here to Skip to main content

Custom ComboBoxes with Advanced Drop-down Features

By , 22 Apr 2003
Rate this:
Please Sign up or sign in to vote.

Preview of cutom comboboxes

CheckComboBox control
DateComboBox control
TreeComboBox 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:

  // 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.

  // 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:

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:

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.

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.

  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.

  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)

About the Author

Oleksandr Kucherenko
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? PinmemberMember 1019604612-Aug-13 12:32 
Question.NET 4.0 Pinmembermoep12321-Nov-12 8:51 
AnswerRe: .NET 4.0 Pinmemberm.elabbady29-Mar-14 5:28 
QuestionThank you!!!! Pinmemberreixuemin20-Oct-11 15:29 
GeneralCheckBoxes With Nodes PinmemberFarid_Bilal26-Feb-09 20:15 
QuestionCan you help me in ASP.Net,please. Pinmemberlove_big_cat2-Apr-08 16:20 
QuestionHow refresh the combo items in RunTime? [modified] PinmemberJhon Williams Munoz14-Sep-07 8:44 
QuestionRightToLeft? Pinmemberperspolis21-May-07 5:14 
QuestionUnder XP - how to remove horizontal scrollbar PinmemberVegemite12-Oct-06 9:31 
GeneralExpand automatically PinmembersylvainOz5-Jun-06 20:24 
GeneralTurning Checkcombo into normal combo Pinmemberkrismadair17-May-06 22:52 
GeneralSuggestion Pinmemberrncwnd5-May-06 4:27 
GeneralQuestion regarding combo boxes. Pinmemberna.nu5-May-06 0:37 
AnswerRe: Question regarding combo boxes. PinmemberAlex Kucherenko5-May-06 1:12 
GeneralSorted Nodes??ß Pinmemberlangdar113-Feb-06 4:06 
AnswerRe: Sorted Nodes??ß PinmemberAlex Kucherenko17-May-06 5:04 
GeneralRe: Sorted Nodes??ß PinmemberMember 36472086-Mar-09 23:49 
GeneralThe dateTime combo box has error in Chinese systems PinmemberYefu Wang2-Feb-06 16:48 
General&quot;Deletable&quot; but not can not &quot;Write&quot; Pinmembersabankocal2-Jun-05 20:58 
GeneralDefault Xp Style View Pinmembersabankocal1-Jun-05 22:44 
GeneralRe: Default Xp Style View PinmemberAlex Kucherenko2-Jun-05 0:16 
GeneralRe: Default Xp Style View PinmemberSkaterGirl7-Jun-06 6:29 
AnswerRe: Default Xp Style View PinmemberAlex Kucherenko7-Jun-06 21:30 
Generalusing buttons to go up and down and select items in combo box with checkboxes PinsussAnonymous9-Feb-05 4:57 
General!!! new version of control !!! PinmemberAlex Kucherenko5-Jan-04 23:13 

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 | Mobile
Web02 | 2.8.140421.2 | Last Updated 23 Apr 2003
Article Copyright 2003 by Oleksandr Kucherenko
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid