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

ComboBox with Suggestions Based on Loose Character Search

, 26 May 2014 LGPL3
Rate this:
Please Sign up or sign in to vote.
A ComboBox whose suggestion list is based on loose character search

Introduction

I wanted to have a ComboBox with completion as powerful as the ones found in SublimeText or in Resharper.

As with the standard AutoComplete feature, the suggestion list is based on the items of the combo. But instead of displaying the items in which text begins with the search string, it displays the items in which text contains all the characters of the search string but not consecutively.

The list is updated as the search text changes and in each suggestion, the matched characters are displayed in bold.

For example, in the screenshot above, "johns" is matched against:

  • Eyvind Johnson
  • Johannes Vilhelm Jensen
  • John Galsworthy
  • John Steinbeck
  • ...

Another available way of matching combo items against user input, is to match all the characters of the input string consecutively and to allow the wildcard '*'. This wildcard matches any sequence of characters.

For example, in the screenshot above, "john*s" is matched against:

  • Eyvind Johnson
  • John Galsworthy
  • John Steinbeck
  • Saint-John Perse

A third available matching method simply use native .NET Regexs:

For example, in the screenshot above, "john[^a]*s" is matched against:

  • Eyvind Johnson
  • John Steinbeck
  • Saint-John Perse

Background

I've borrowed a lot of code from the following two CodeProject articles:

Using the Code

This ComboBox can be used as any standard WinForm ComboBox. Just build the DLL and in the form designer, drag the combo from the Toolbox to your form.

The algorithm used for matching ComboBox items is set with the property MatchingMethod. It can take the values:

  • StringMatchingMethod.NoWildcards
  • StringMatchingMethod.UseWildcards
  • StringMatchingMethod.UseRegexs

The following properties should not be set:

  • DropDownStyle
  • AutoCompleteSource, AutoCompleteMode, ...

The maximum height of the dropdown is based on the property ItemHeight . Its width is based on the property DropDownWidth. Unless overridden, DropDownWidth is set to the width of the combo.

I recommend to use another font than the standard "Microsoft Sans Serif". There is no bold version of "Microsoft Sans Serif" and so the rendering of bold characters is quite poor. "Segoe UI" is a very good substitute.

Points of Interest

The EasyCompletionComboBox is a control derived from the standard ComboBox. Every time, the user modifies the contents of the edit control of the combobox, a custom dropdown is shown or updated.

The custom dropdown is derived from ToolStripDropDown and contains a standard ListBox.

The combo text is matched against all the items of the combo and a list of StringMatch is built. This list is used as the items of the dropdown's listbox.

public class StringMatch
{
    /// <summary>
    /// The original source
    /// </summary>
    public string Text { get; private set; }
    /// <summary>
    /// The source decomposed on matches/non matches against the pattern
    /// </summary>
    internal List<string> Segments { get; private set; }
    /// <summary>
    /// Is the first segment a match?
    /// </summary>
    internal bool StartsOnMatch { get; private set; }
} 

As the search is done, the strings are split into segments. These segments are used when rendering the strings in the listbox for alternating bold and non-bold portions.

private void onSuggestionListDrawItem(object sender, DrawItemEventArgs e)
{
    StringMatch sm = (StringMatch) m_suggestionList.Items[e.Index];
    e.DrawBackground();
    
    bool isBold = sm.StartsOnMatch;
    Rectangle rBounds = e.Bounds;
    foreach (string s in sm.Segments)
    {
        Font f = isBold ? m_boldFont : Font;
        DrawString(e.Graphics, e.ForeColor, ref rBounds, s, f);
        isBold = !isBold;
    }
    e.DrawFocusRectangle();
} 

The keyboard focus is set to the combo and not to the dropdown. So special keys like arrows or escape are translated into commands for the dropdown.

The automatic closing of the dropdown is a little tricky. I would have expected to use the AutoClose property of ToolStripDropDown, but unfortunately ToolStripManager steals the keyboard events when AutoClose is set. So an application IMessageFilter is set in order to detect when the user clicks outside the control and then the dropdown is closed.

History

  • 07 April 2014: First release
  • 09 April 2014: Version 1.0.1
    • Bug fix: When the "standard" dropdown was visible and the user has entered text in the edit box of the combo, this text was incorrectly replaced by something else
    • Bug fix: Incorrect test for the visibility of the dropdown
  • 13 April 2014: Version 1.0.2
    • Bug fix: Now the completion dropdown is only shown when the user enters text in the edit control of the combobox
  • 19 April 2014: Version 1.1.1
    • Bug fix: The tab key is now correctly handled
    • New feature: Added two ways of matching combo items against user input
      • Simple matching with '*' wildcards
      • Regex matching
  • 23 April 2014: Version 1.1.2
    • Bug fix: Fixed bug in the "Wildcard" string matching algorithm
  • 24 April 2014: Version 1.1.3
    • Bug Fix: Completely rewritten the "Wildcard" string matching algorithm
  • 26 May 2014: Version 1.1.4
    • Bug Fix: Better handling of when to show the completion list
  • 8 June 2014: version 1.1.5
    • Bug Fix: Uploaded incorrect version of wildcard completion in previous release
    • Bug Fix: Correct handling of clicking in non-client areas of the suggestion list box
    • Bug Fix: Ampersands are now correctly displayed
    • Bug Fix: The suggestion list box now uses the control font
    • Thanks to omzig for his bug reports and suggestions

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author

Serge Weinstock
Web Developer
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
BugBold Font Size Bug - Fixed [modified] Pinmemberomzig7-Jun-14 6:21 
GeneralRe: Bold Font Size Bug - Fixed PinmemberSerge Weinstock8-Jun-14 9:01 
BugBug in PreFilterMessage, drop down box scroll bar doesn't work Pinmemberomzig4-Jun-14 16:02 
GeneralRe: Bug in PreFilterMessage, drop down box scroll bar doesn't work PinmemberSerge Weinstock8-Jun-14 6:14 
GeneralRe: Bug in PreFilterMessage, drop down box scroll bar doesn't work Pinmemberomzig9-Jun-14 5:00 
BugWild Card Not working - Fixed [modified] Pinmemberomzig3-Jun-14 5:38 
GeneralRe: Wild Card Not working - Fixed PinmemberSerge Weinstock8-Jun-14 0:26 
QuestionGetting an error when trying to download the sample PinmemberJonathan Reis19-May-14 15:14 
I'm getting an error when trying to download the source:
 
/KB/combobox/755707/EasyCompletionComboBox.zip appears to be missing on our servers. D'oh.
 
Has it been moved somewhere?
 
Thanks in advance
AnswerRe: Getting an error when trying to download the sample PinmemberSerge Weinstock26-May-14 7:39 
GeneralRe: Getting an error when trying to download the sample Pinmemberahamedgad28-May-14 13:12 
GeneralRe: Getting an error when trying to download the sample PinmemberSerge Weinstock28-May-14 18:31 
GeneralRe: Getting an error when trying to download the sample Pinmemberahamedgad4-Jun-14 12:19 
Generalnice PinmemberCosmic_Spy10-Apr-14 20:06 
QuestionA good attempt but... Pinprofessional i0010-Apr-14 2:35 
QuestionNicely done! PinprofessionalRavi Bhavnani9-Apr-14 17:49 
QuestionBuild .dll ? PinmemberMember 107298747-Apr-14 23:40 
AnswerRe: Build .dll ? PinmemberSerge Weinstock8-Apr-14 8:43 
QuestionCombox - Web Pinmemberpradeepvpanzade7-Apr-14 5:03 
AnswerRe: Combox - Web PinmemberSerge Weinstock7-Apr-14 8:45 
GeneralMy vote of 5 PinmemberPolinia7-Apr-14 2:49 

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.141220.1 | Last Updated 26 May 2014
Article Copyright 2014 by Serge Weinstock
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid