Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

ComboBox with AutoComplete 1.1
By James Williams

I wrote the original ComboBox with AutoComplete about a year ago for a project I was working on at the time. Well, I updated it a few times after I posted it here. I have received several e-mails from programmers telling me that the original code had some serious problems, especially when the ACComboBox was databound, and asking for a solution.

Well, I decided to re-write the control to make it function properly. Please note the following:

  • The AutoComplete feature is sequential, i.e., if "James" comes before "Jack" in your list, then the AutoComplete will select "James" when you type "J". If you select the control's Sorted attribute as True, then "Jack" will be selected. Basically, it finds the first match in the list and selects it.
  • The AutoComplete feature is not case-sensitive. It uses the ComboBox's FindString method which is not case-sensitive. I think most would prefer it this way anyhow.

I have zipped up the Visual Studio solution files. Also, the final compiled DLL is within the the Release folder. The main code is below.

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace DigitalCult
{
    /// <summary>
    /// Summary description for ACComboBox.
    /// </summary>
    public class ACComboBox : System.Windows.Forms.ComboBox
    {         private bool autoComplete;

        [DefaultValue(true),
        Description("Auto-completes text if a match is found in the items collection."),
        Category("Behavior")]
        public bool AutoComplete
        {
            get { return autoComplete; }
            set { autoComplete = value; }
        }

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private Container components = null;

        /// <summary>
        /// Default constructor.
        /// </summary>
        public ACComboBox()
        {
            // This call is required by the Windows.Forms Form Designer.
            InitializeComponent();

            // Add any initialization after the InitComponent call
            this.autoComplete = true;
            this.KeyPress += new KeyPressEventHandler( this.OnKeyPress );
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if( components != null )
                    components.Dispose();
            }
            base.Dispose( disposing );
        }

        private void OnKeyPress( object sender, KeyPressEventArgs e )
        {
            if ( autoComplete )
            {
                ACComboBox acComboBox = (ACComboBox)sender;
                if ( !e.KeyChar.Equals( (char)8 ) )
                {
                    SearchItems( acComboBox, ref e );
                }
                else
                    e.Handled = false;
            }
            else
                e.Handled = false;
        }

        /// <summary>
        /// Searches the combo box item list for a match and selects it.
        /// If no match is found, then selected index defaults to -1.
        /// </summary>
        ///
        ///
        private void SearchItems( ACComboBox acComboBox, ref KeyPressEventArgs e )
        {
            int selectionStart = acComboBox.SelectionStart;
            int selectionLength = acComboBox.SelectionLength;
            int selectionEnd = selectionStart + selectionLength;
            int index;
            StringBuilder sb = new StringBuilder();

            sb.Append( acComboBox.Text.Substring( 0, selectionStart ) )
                .Append( e.KeyChar.ToString() )
                .Append( acComboBox.Text.Substring( selectionEnd ) );
            index = acComboBox.FindString( sb.ToString() );
            
            if ( index == -1 )
                e.Handled = false;
            else
            {
                acComboBox.SelectedIndex = index;
                acComboBox.Select( selectionStart+1, acComboBox.Text.Length-(selectionStart+1) );
                e.Handled = true;
            }
        }

        #region Component Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }
        #endregion
    }
}

Download Source