ComboBox AutoComplete on SubString

前端 未结 5 703
-上瘾入骨i
-上瘾入骨i 2020-12-02 21:26

In one of my WinForms applications, I have a window with a ComboBox for the user to select a customer from.

The customers in this list box are in this format : \"Cus

5条回答
  •  独厮守ぢ
    2020-12-02 22:02

    Here's my code for a databound combobox (in my case an Access DB). You add a a combobox and listbox to the form. Then, use my code below as a reference as it shows:

    1. How to update the databound combobox
    2. Add event handlers such that when you use the arrow keys in the combobox it goes through the results in the listbox.
    3. Use a timer to limit database queries to only when 500ms has elapsed since last keypress.

    I'm sure there are better ways of doing some of this. This code is "works for me". Critiques are appreciated.

        #region AutoComplete Organization Box
    
        System.Windows.Forms.Timer mOrganizationTextChangedTimer = null;
        void organizationComboBox_TextChanged(object sender, System.EventArgs e)
        {
            if (mOrganizationTextChangedTimer == null)
            {
                mOrganizationTextChangedTimer = new System.Windows.Forms.Timer();
                mOrganizationTextChangedTimer.Interval = 500;
                mOrganizationTextChangedTimer.Tick += new EventHandler(mOrganizationTextChangedTimer_Tick);
            }
            mOrganizationTextChangedTimer.Enabled = true;
        }
    
        void mOrganizationTextChangedTimer_Tick(object sender, EventArgs e)
        {
            mOrganizationTextChangedTimer.Enabled = false;
            UpdateOrganizationNameAutocompleteResults( comboBoxOrganizationName.Text );    
        }
    
        void UpdateOrganizationNameAutocompleteResults( string pSearchString ) 
        {
            listBoxOrganizationAutocompleteResults.Items.Clear();
            if (comboBoxOrganizationName.Text.Length == 0)
            {
                HideOrganizationNameAutocompleteResults();
                return;
            }
    
            // Added a custom query to search our database and return results that match.  The query uses UCase on the columns.
            allertDataSet3.OrganizationDataTable orgs = organizationTableAdapter.GetDataByOrganizationNameSearchUCase("%" + pSearchString.ToUpper() + "%", "%" + pSearchString.ToUpper() + "%");
    
            foreach( allertDataSet3.OrganizationRow r in orgs ) {
                string longName = r.OrganizationName;
                listBoxOrganizationAutocompleteResults.Items.Add(longName);
                listBoxOrganizationAutocompleteResults.Visible = true;
                listBoxOrganizationAutocompleteResults.BringToFront();
            }
    
            // This Code block is needed because once you select an organization, the combobox text changes which forces another search.
            // There is only one result from that search so this hides it when the search result equals the already selected combobox.
            try {
                System.Data.DataRowView drv = (System.Data.DataRowView) comboBoxOrganizationName.SelectedItem;
                allertDataSet3.OrganizationRow orgRow = (allertDataSet3.OrganizationRow)drv.Row;
    
                if ( listBoxOrganizationAutocompleteResults.Items.Count == 1 && 
                    ((string)listBoxOrganizationAutocompleteResults.Items[0]).Equals(orgRow.OrganizationName) )
                {
                    HideOrganizationNameAutocompleteResults();
                }
            }
            catch {
                // do nothing
            }            
        }
    
        void organizationComboBoxAutocompleteResults_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            foreach (System.Data.DataRowView drv in comboBoxOrganizationName.Items)
            {
                Alertus.Allert.allertDataSet3.OrganizationRow orgRow = (Alertus.Allert.allertDataSet3.OrganizationRow)drv.Row;
                if (orgRow.OrganizationName.Equals((string) listBoxOrganizationAutocompleteResults.SelectedItem))
                {
                    // Prevents it from searching again.
                    comboBoxOrganizationName.TextChanged -= organizationComboBox_TextChanged;
                    comboBoxOrganizationName.SelectedItem = drv;
                    comboBoxOrganizationName.TextChanged += organizationComboBox_TextChanged;
                    HideOrganizationNameAutocompleteResults();
                    return;
                }
            }
    
            // This is basically an error... it should have found it.
            HideOrganizationNameAutocompleteResults();
        }
    
        void listBoxOrganizationAutocompleteResults_LostFocus(object sender, System.EventArgs e)
        {
            HideOrganizationNameAutocompleteResults();
        }
    
        void HideOrganizationNameAutocompleteResults()
        {
            listBoxOrganizationAutocompleteResults.Visible = false;
        }
    
        private void listBoxOrganizationAutocompleteResults_MouseClick(object sender, MouseEventArgs e)
        {
            // When mouse is clicked we assume user made a seletion.
            organizationComboBoxAutocompleteResults_SelectedIndexChanged(null, null);
        }
    
        /// 
        /// Redirects the Arrow keys to update the selected index in the autocomplete list box.
        /// 
        /// 
        /// 
        private void comboBoxOrganizationName_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                if (listBoxOrganizationAutocompleteResults.Items.Count >= 1 && listBoxOrganizationAutocompleteResults.Visible)
                {
                    if (listBoxOrganizationAutocompleteResults.SelectedIndex < 0)
                    {
                        listBoxOrganizationAutocompleteResults.SelectedIndex = 0;
                    }
                    else
                    {
                        listBoxOrganizationAutocompleteResults.SelectedIndex = (listBoxOrganizationAutocompleteResults.SelectedIndex - 1) % listBoxOrganizationAutocompleteResults.Items.Count;
                    }
                }
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Down)
            {
                if (listBoxOrganizationAutocompleteResults.Items.Count >= 1 && listBoxOrganizationAutocompleteResults.Visible )
                {
                    if (listBoxOrganizationAutocompleteResults.SelectedIndex < 0)
                    {
    
                        listBoxOrganizationAutocompleteResults.SelectedIndex = 0;
                    }
                    else
                    {
                        listBoxOrganizationAutocompleteResults.SelectedIndex = (listBoxOrganizationAutocompleteResults.SelectedIndex + 1) % listBoxOrganizationAutocompleteResults.Items.Count;
                    }
                }
    
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Enter)
            {
                e.Handled = true;
                if (listBoxOrganizationAutocompleteResults.Visible)
                {
                    organizationComboBoxAutocompleteResults_SelectedIndexChanged(null, null);
                }
            }
        }
    
        #endregion
    

    Designer Code:

        // 
        // comboBoxOrganizationName
        // 
        this.comboBoxOrganizationName.FormattingEnabled = true;
        this.comboBoxOrganizationName.Location = new System.Drawing.Point(19, 53);
        this.comboBoxOrganizationName.Name = "comboBoxOrganizationName";
        this.comboBoxOrganizationName.Size = new System.Drawing.Size(363, 21);
        this.comboBoxOrganizationName.TabIndex = 1;
        this.comboBoxOrganizationName.SelectedIndexChanged += new System.EventHandler(this.comboBoxOrganizationName_SelectedIndexChanged);
        this.comboBoxOrganizationName.Enter += new System.EventHandler(this.comboBoxOrganizationName_Enter);
        this.comboBoxOrganizationName.KeyDown += new System.Windows.Forms.KeyEventHandler(this.comboBoxOrganizationName_KeyDown);
        this.comboBoxOrganizationName.TextChanged += new System.EventHandler(this.organizationComboBox_TextChanged);**
    
      // 
                // listBoxOrganizationAutocompleteResults
                // 
                this.listBoxOrganizationAutocompleteResults.FormattingEnabled = true;
                this.listBoxOrganizationAutocompleteResults.Location = new System.Drawing.Point(20, 76);
                this.listBoxOrganizationAutocompleteResults.Name = "listBox1";
                this.listBoxOrganizationAutocompleteResults.Size = new System.Drawing.Size(359, 95);
                this.listBoxOrganizationAutocompleteResults.TabIndex = 19;
                this.listBoxOrganizationAutocompleteResults.Visible = false;
                this.listBoxOrganizationAutocompleteResults.MouseClick += new System.Windows.Forms.MouseEventHandler(this.listBoxOrganizationAutocompleteResults_MouseClick);
                this.listBoxOrganizationAutocompleteResults.Leave += new System.EventHandler(this.listBoxOrganizationAutocompleteResults_LostFocus);
    

提交回复
热议问题