Click here to Skip to main content
15,867,488 members
Articles / Web Development / HTML

ExCB - Extended Multi Column ComboBox

Rate me:
Please Sign up or sign in to vote.
4.77/5 (31 votes)
21 Mar 2016CPOL6 min read 76.8K   3.6K   43   51
Presenting an easy-to-use, flexible, filterable ComboBox, managing various data types (including images), also sortable, resizable and reordable columns

Sample Image - maximum width is 600 pixels

Introduction

This component, written in VB.NET, was first produced in 2008. But recently, I decided to introduce some new features, especially in the ListView part. Some reasons are listed below:

  • The need to present Images and good 'CheckBoxes', not just those resulting from the use of characters from the Wingdings font.
  • The need to automatically adjust the height of the subcomponents, given the use of different fonts and font sizes.
  • The need to 'correctly' sort Text, Numeric and Date(Time) Columns.
  • A fact which irritated everyone: with Visual Studio 2008 on Windows XP, increasing the font size did not change the height of the ListView header. Annoying... So, I also decided to impose the Header Height.

Thus, the control became, not only 'one more ComboBox', but an enhanced, flexible, powerful and easy-to-use component.

  • It works with various types of data: Text, Numbers, Date(Time), Images and Booleans
  • Images can be sent as (real) images or by path reference
  • Booleans are shown as 'checkboxes', but in 2 ways: by picture (better aspect, scalable), or by characters from Wingdings font (higher performance)
  • Has a built-in Row Counter
  • Rows can be filtered, in order to reduce the list, by typing characters in the TextBox
  • The user can control the List Header Height and Colors
  • The user can control the List Rows Height
  • The user can control each Column's Fore & Back Colors
  • The user can control the Size and SizeMode of Images and 'picture checkboxes'
  • Columns can be Resized, Reordered and Sorted (ascending/descending, with Arrow indicator)
  • Numbers and Dates are 'effectively' ordered, regardless of the Format in which they are displayed

Image 2

Of course, the more images are added, the worse the performance...

Programming

Also, the code is as simple as possible, and programmers can find some useful code snippets, related to:

  • Expandable properties
  • Fading effects
  • Color change
  • Embedded controls handling
  • HeaderControl subclassing (NativeWindow)
  • HDM_LAYOUT capture
  • Header Height control
  • Header Sort Arrows
  • Columns Text, Date & Numeric effective sorting

See Documentation and Examples

First of all, download the .ZIP file.

The .ZIP file includes ExCB_Documentation.PDF, which fully describes the component.
The demo forms present several examples, techniques and tips to manipulate data.

Last Updates

  1. Addendum to ExCB_Documentation.PDF:
    Filtering - To reset filtering, selecting all Rows, just drop-down the List clicking the mouse right-button.
  2. When starting the provided solution, if you receive the message 'A project with an Output Type of Class Library cannot be started directly', then:
    Go to the Solution Explorer, select ExCB_Test Project, right-click mouse button and click Set as StartUp Project.
  3. Addendum to ExCB_Documentation.PDF: Take note of another Event:
    Event DropDownChanged - Occurs when the List is Opened/Closed.
    Syntax:
    VB.NET
    DropDownChanged(IsDroppedDown as Boolean)
    
    Remarks:
    - IsDroppedDown = True - The List was Opened
    - IsDroppedDown = False - The List was Closed
  4. To avoid an error, in a very specific circumstance, please,
    in Class ExCB.vb, Property SelectedIndex(), replace the line:
    VB.NET
    MyLV1.Items(value).Selected = True
    
    with:
    VB.NET
    Try
        MyLV1.Items(value).Selected = True
    Catch
    End Try
    
  5. In response to questions posed by L.Botello:
    1. ...it seems that, in certain circumstances, when font size is increased, the list is slightly truncated (bottom). Isn't?
      Yes, it's a bug. To fix it, please:
      in ExCB.vb, Region "TextBox & Button code", Sub Button1_MouseDown, replace the line:
      VB.NET
      Dim LX As Integer = Sizes_.ListHeader_Height + 1 + MX * (_ListRowHeight + 1)
      with:
      VB.NET
      Dim LX As Integer = Math.Max(Sizes.ListHeader_Height, _
                              TextRenderer.MeasureText(" ", Me.Font).Height + 4) + _
                              MX * (_ListRowHeight + 1)
    2. Did you ever have considered the possibility of growing/shrink the list (regardless of MaxRowsDisp property value) when the form is resized?
      Thank you for the suggestion, that will improve control's features.
      It will be an option. Please, do the following:
      in Class ExCB.vb, Region "Public Methods", insert the following Sub:
      VB.NET
      Public Sub AdjustListHeight()
          Try
              Dim Parent_csH As Integer = Me.ParentForm.ClientSize.Height ' Exclude TitleBar and Borders
              Dim HeaderH = Math.Max(Sizes.ListHeader_Height, TextRenderer.MeasureText(" ", Me.Font).Height + 4)
              Dim RestH As Integer = Parent_csH - Me.Top - MyLV1.Top - HeaderH
              _MaxDsp = RestH \ (_ListRowHeight + 1)
              Dim MinRows As Integer = Math.Min(_MaxDsp, MyLV1.Items.Count + 1)
              If MyLV1.Visible Then
                  MyLV1.Height = HeaderH + MinRows * (_ListRowHeight + 1)
                  Me.Height = _LblBoxH + MyLV1.Height
              Else
                  _HideLV()
              End If
          Catch
          End Try
      End Sub
      Then, in your Form, insert this code and invoke the Method just for the Control instance(s) you want the feature active:
      VB.NET
      Private Sub Me_Sizes(sender As Object, e As EventArgs) Handles Me.Resize, Me.SizeChanged
          ExCB1.AdjustListHeight()
          ' ...
          ' ExCBn.AdjustListHeight()
      End Sub
      Anyway, define MaxRowsDisp value for the first display (when it occurs before the first resize...).
  6. Made available for download a new project (source and demo), for VS2012, which is the 'original' plus all the above updates (including Method AdjustListHeight), plus a new Property AutoComplete, which gives the Control AutoComplete-like capabilities: whenever a key is pressed, the List drops down, showing only the rows that matches the typed string. The match applies to any subitem (Column). Setting the Property AutoComplete to True implies Property Filterable to be also set to True. Before running ExCB_Test project, don't forget to Set it as StartUp Project.

Using the Code

The component is provided in 2 versions: Visual Studio 2008 and Visual Studio 2012.
All features are available in both versions, but version 2012 is less limited and easier to use.

The component DLL is located at ...\ExCB\VS20xx\ExCB\bin\Release\ExCB.dll.

  • Add it to your Toolbox, right-clicking the Toolbox area -> Choose Items… -> Browse -> select the DLL
  • In the Solution Explorer, select your Project, open My Project -> References -> Add… -> Browse -> select the DLL
  • Drag the component from the Toolbox to your Form.

Brief Description of the Component's Own Properties, Event and Methods

Browsable Properties

  • BorderStyle The BorderStyle which applies to the TextBox subcomponent
  • Colors (Expandable Property)
    • HeadBackColor - BackColor of the ListView Header
    • HeadForeColor - ForeColor of the ListView Header
    • ListBackColor - BackColor of the ListView Items
    • ListForeColor - ForeColor of the ListView Items
    • TBoxBackColor - BackColor of TextBox element
    • TBoxForeColor - ForeColor of TextBox element
  • CounterLoc - The position and alignment of the built-in Row Counter, relative to the TextBox
  • DisplayColumn - The Index of the SubItem (Column) to display in the TextBox, when selecting a Row in the List
  • Filterable - Indicates if the ListView Rows can/cannot be filtered
  • Font - Defines the Font Name, Size and Styles for ALL the subcomponents (ListView, TextBox and Counter)
  • GridLines - Displays grid lines around Items and SubItems, in the ListView
  • MaxRowsDisp - Maximum number of Rows to display, when the List is dropped-down
  • MinimunWidth - Minimum Width of the component. Changes when the component is resized
  • Read_Only - When True, the component cannot be dropped-down / changed, but shows the current selection
  • Reordable - Indicates if the ListView Columns can/cannot be reordered
  • Resizable - Indicates if the ListView Columns can/cannot be resized
  • Sizes - (Expandable Property)
    • Image_Height - Height of the Images sent to the List
      • Image_Width - Width of the Images sent to the List
      • ListHeader_Height - Height of the ListView Header
      • ListRow_Height - Height of the ListView Rows
      • YesNo_Height - Height (and Width) of the "checkboxes"
  • Sortable Indicates if the ListView Columns can/cannot be sorted

Non-browsable Properties

  • Count - Gets the number of Rows in the List
  • SelectedIndex - Gets / Sets the Index of the Row currently selected
  • Text - Gets / Sets the Text from/to the TextBox part of the component

Events

  • ItemSelected - Occurs when a Row is Selected / programmatically Unselected
  • DropDownChanged - Occurs when the List is Opened/Closed

Methods

  • AddColumn - Creates a new Column (with 1 required and 13 optional parameters)
    Syntax:
    VB.NET
    AddColumn(HeaderText As String,
        [Width As Integer = 80],
        [Align As System.Windows.Forms.HorizontalAlignment = HorizontalAlignment.Left],
        [DataType As ExCB.ExCB.DataType = ExCB.ExCB.DataType._Text],
        [Format As String = Nothing],
        [ForeColor As System.Drawing.Color = Nothing], '(VS2012)
        [BackColor As System.Drawing.Color = Nothing], '(VS2012)
        [ImgWidth As Integer = 0],
        [ImgHeight As Integer = 0],
        [SizeMode As ExCB.ExCB.SizeMode = ExCB.ExCB.SizeMode._Stretch],
        [Resizable As Boolean = True],
        [Reordable As Boolean = True],
        [Sortable As Boolean = True],
        [ArrowOnRight As Boolean = False])
  • AddRow - Adds a Row (Item) to the ListView (sends a String or Object Array)
  • ARGB - Converts a Color to its Integer value
  • Clear - Deletes all Rows of the List (including Embedded Controls), optionally all Columns
  • RowSelect - Selects a Row, giving a Value and a Column Index, optionally returning another subitem
  • GetImage - Retrieves the Image at the specified Index within the Component's array

History

03.Jun.2014 - First posted

05.Jun.2014 - Added Last Updates 1. and 2. to See Documentation and Examples

11.Jun.2014 - Added Last Updates 3. and 4. to See Documentation and Examples

05.Dec.2014 - Added Last Updates 5. to See Documentation and Examples

21.Mar.2016 - Added Last Updates 6. to See Documentation and Examples

License

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


Written By
Retired
Portugal Portugal
Working on computers since Mar,6 1969
Languages: RPN, Fortran, COBOL, Univac 1100 Meta-assembler, Basic, Z80 Assembly, 8086 Assembly, IBM Assembler (360/370, 38xx, 43xx), Clipper, ANSI C, SQL, Visual Basic, VBA, VB.NET
Lately, some HTML, JavaScript, C#
Actually retired, but still developing (for pleasure).

Comments and Discussions

 
GeneralMy vote of 5 Pin
la_plume0916-Feb-24 14:32
la_plume0916-Feb-24 14:32 
QuestionWhy first column is always aligned to left ? Pin
la_plume0916-Feb-24 7:05
la_plume0916-Feb-24 7:05 
GeneralMy vote of 5 Pin
MDT MTO4-Aug-22 18:27
MDT MTO4-Aug-22 18:27 
QuestionGave this a vote of 5 Pin
LiveForCaffeine10-Sep-19 5:40
LiveForCaffeine10-Sep-19 5:40 
AnswerRe: Gave this a vote of 5 Pin
Avelino Ferreira29-Dec-19 23:31
professionalAvelino Ferreira29-Dec-19 23:31 
QuestionThanks and a few questions Pin
Bucknut75116-Mar-16 2:22
Bucknut75116-Mar-16 2:22 
AnswerRe: Thanks and a few questions Pin
Avelino Ferreira16-Mar-16 9:20
professionalAvelino Ferreira16-Mar-16 9:20 
GeneralRe: Thanks and a few questions Pin
Bucknut75117-Mar-16 4:24
Bucknut75117-Mar-16 4:24 
GeneralRe: Thanks and a few questions Pin
Avelino Ferreira17-Mar-16 13:34
professionalAvelino Ferreira17-Mar-16 13:34 
GeneralRe: Thanks and a few questions Pin
Bucknut75118-Mar-16 3:40
Bucknut75118-Mar-16 3:40 
GeneralRe: Thanks and a few questions Pin
Avelino Ferreira18-Mar-16 4:38
professionalAvelino Ferreira18-Mar-16 4:38 
GeneralRe: Thanks and a few questions Pin
Bucknut75118-Mar-16 5:32
Bucknut75118-Mar-16 5:32 
GeneralRe: Thanks and a few questions Pin
Avelino Ferreira18-Mar-16 16:47
professionalAvelino Ferreira18-Mar-16 16:47 
QuestionQuestion and Problem(?) Pin
DanW5221-Dec-15 11:12
professionalDanW5221-Dec-15 11:12 
AnswerRe: Question and Problem(?) Pin
Avelino Ferreira27-Dec-15 13:34
professionalAvelino Ferreira27-Dec-15 13:34 
GeneralRe: Question and Problem(?) Pin
DanW5229-Dec-15 6:41
professionalDanW5229-Dec-15 6:41 
GeneralRe: Question and Problem(?) Pin
Avelino Ferreira31-Dec-15 1:44
professionalAvelino Ferreira31-Dec-15 1:44 
BugConversion from string "24-06-1987" to type 'Double' is not valid. Pin
sreeyush sudhakaran19-Oct-15 18:33
professionalsreeyush sudhakaran19-Oct-15 18:33 
GeneralRe: Conversion from string "24-06-1987" to type 'Double' is not valid. Pin
Avelino Ferreira22-Oct-15 3:32
professionalAvelino Ferreira22-Oct-15 3:32 
Hi, Sreeyush

Such an error (conversion from Date String to Double) does not occur in the indicated comparison instruction, but 6/7 lines above, in the Conversion instructions:
VB
vX = CDate(CType(x, ListViewItem).SubItems(_Column).Text).ToOADate
vY = CDate(CType(y, ListViewItem).SubItems(_Column).Text).ToOADate
In my (and many others, I supppose) environment, the instruction
VB
Dim D As Double = CDate("24-06-1987").ToOADate()
assigns to D the value 31952
But also "24.06.1987", "24/06/1987", and others, like "1987/06/24", works fine...
"ToOADate" is a member of "System.Date"

However, in the error log I can see:
Message="Input string was not in a correct format."
So, I think the problem should be that your environment (Locale Date Format) does not allow such a format.

I suggest choosing a valid Date Format and specify it in the instruction
VB
Excb1.AddColumn("Birth Date", , HorizontalAlignment.Center, ExCB.ExCB.DataType._Date, "dd-MM-yyyy")
[ File Form1, Sub Players_Column_Definitions() ]
GeneralRe: Conversion from string "24-06-1987" to type 'Double' is not valid. Pin
sreeyush sudhakaran23-Oct-15 8:05
professionalsreeyush sudhakaran23-Oct-15 8:05 
Questiontoo young to retire Pin
zpaulo_carraca9-Dec-14 5:50
zpaulo_carraca9-Dec-14 5:50 
AnswerRe: too young to retire Pin
Avelino Ferreira9-Dec-14 6:56
professionalAvelino Ferreira9-Dec-14 6:56 
QuestionTwo questions (maybe a challenge?) Pin
L.Botello1-Dec-14 4:35
L.Botello1-Dec-14 4:35 
AnswerRe: Two questions (maybe a challenge?) Pin
Avelino Ferreira5-Dec-14 5:25
professionalAvelino Ferreira5-Dec-14 5:25 
GeneralRe: Two questions (maybe a challenge?) Pin
L.Botello8-Dec-14 4:49
L.Botello8-Dec-14 4:49 

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.