C#组合框搜索列表中的任何位置,而不仅仅是使用数据表过滤器的第一个字母

时间:2014-11-26 12:18:07

标签: c# combobox

我想实现组合框(在列表中的任何地方搜索,而不仅仅是第一个字母)。我看到this here但没有帮助我。

我使用以下代码

 private void cmbMenuName_TextChanged(object sender, EventArgs e)
    {
           DataTable dt = dtMenuOriginal;//dtMenuOriginal-Orginal data
      dt.DefaultView.RowFilter = string.Format("MenuName LIKE '%{0}%'", cmbMenuName.Text);

          cmbMenuName.DataSource = dt;
     }

此代码仅适用于第一个字符按,请告诉我将要调用哪个事件或以其他方式解决此问题

2 个答案:

答案 0 :(得分:0)

我使用此Link,这对自动完成文本框控件很有用。 我的代码 -

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

namespace Combo_MiddleText_AutocompleteDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //don't forget to create/initialize our own autocomplete listbox
            this.InitializeAutoComplete();
        }
        private void InitializeAutoComplete()
        {
            this.SuspendLayout();
            //Create a new listbox that will be shown for the auto-complete
            // 
            // _listBox
            // 
            _listBox = new System.Windows.Forms.ListBox();
            _listBox.Visible = false;
            _listBox.Location = new System.Drawing.Point(0, 0);
            _listBox.Name = "_listBox";
            _listBox.Size = new System.Drawing.Size(120, 96);
            _listBox.TabIndex = 0;
            _listBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this._listBox_MouseDown);
            // 
            // AutoCompleteTextBox - attach some events
            // 
            cmbMenuName.KeyDown += new System.Windows.Forms.KeyEventHandler(this.cmbMenuName_KeyDown);
            cmbMenuName.KeyUp += new System.Windows.Forms.KeyEventHandler(this.cmbMenuName_KeyUp);
            this.ResumeLayout(false);
        }
        #region Variables

    Hashtable hash;
    private String[] _values;

    private ListBox _listBox;
    private bool _isAdded;
    private String _formerValue = String.Empty;
    #endregion Variables
    private void Form1_Load(object sender, EventArgs e)
    {
        FillGrid(125);// Menu combobox in Quotation Menu Grid
        cmbMenuName.DroppedDown = false;
    }
    public DataTable FillGrid(int QueryNo)
    {
        try
        {
            hash = new Hashtable();
            DataTable dtReturn = new DataTable();
            hash.Add("@QueryNo", QueryNo);

            //dtReturn= ClsDefination.FillData()
            dtReturn = ClsDefination.FillData("[usp_Transaction_QuotationMaster_Select]", hash);


            if ((dtReturn != null && dtReturn.Rows.Count > 0))// || dtReturn2 != null && dtReturn2.Rows.Count > 0)
            {
                DataRow objRow = dtReturn.Rows[0];
                if (QueryNo == 125) // Menu Name
                {
                    cmbMenuName.DataSource = dtReturn;
                    cmbMenuName.DisplayMember = "MenuName";
                    cmbMenuName.ValueMember = "MenuID";
                    cmbMenuName.Text = "";
                    List<string> list = new List<string>();
                    for (int i = 0; i < dtReturn.Rows.Count; i++)
                    {
                        DataRow dr = dtReturn.Rows[i];


                        list.Add(dr["MenuName"].ToString());



                    }
                    _values = list.ToArray();
                }

            }

            else
            {


            }
            return null;
        }
        catch (Exception)
        {
            return null;
            throw;
        }
    }


    private void cmbMenuName_KeyDown(object sender, KeyEventArgs e)
    {
        //react the arrow up and down
        switch (e.KeyCode)
        {
            case Keys.Down:
                {
                    if ((_listBox.Visible) && (_listBox.SelectedIndex < _listBox.Items.Count - 1))
                    {
                        _listBox.SelectedIndex++;
                    }
                    break;
                }
            case Keys.Up:
                {
                    if ((_listBox.Visible) && (_listBox.SelectedIndex > 0))
                    {
                        _listBox.SelectedIndex--;
                    }
                    break;
                }
        }
    }

    private void cmbMenuName_KeyUp(object sender, KeyEventArgs e)
    {
        //whenever a key is pressed, update the listbox content
        UpdateListBox();
    }


    private void _listBox_MouseDown(object sender, MouseEventArgs e)
    {
        //select the item with the mouse
        if (_listBox.Visible)
        {
            InsertWord((String)_listBox.SelectedItem);
            HideListBox();
            _formerValue = cmbMenuName.Text;
        }
    }


    private void HideListBox()
    {
        //Hide the listbox
        _listBox.Visible = false;
    }
    //private void btnShow_Click(object sender, EventArgs e)
    //{
    //    //when this button is clicked, 
    //    //we take the values from the textbox and list them into the second listbox
    //    lstSelectedValues.Items.Clear();
    //    List<String> selectedValues = SelectedValues;
    //    Array.ForEach(selectedValues.ToArray(),
    //                  selectedValue => lstSelectedValues.Items.Add(selectedValue.Trim()));
    //}
    public List<String> SelectedValues
    {
        get
        {
            //return the list of selection
            String[] result = cmbMenuName.Text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            return new List<String>(result);
        }
    }
    private void UpdateListBox()
    {
        //fill the listbox with the new filtered values
        if (cmbMenuName.Text != _formerValue)
        {
            _formerValue = cmbMenuName.Text;
            String word = GetWord();

            if (word.Length > 0)
            {
                //case insensitive search
                String[] matches = Array.FindAll(_values, x => (x.ToUpper().Contains(word.ToUpper()) && !SelectedValues.Contains(x)));
                if (matches.Length > 0)
                {
                    ShowListBox();
                    _listBox.Items.Clear();
                    Array.ForEach(matches, x => _listBox.Items.Add(x));
                    _listBox.SelectedIndex = 0;
                    _listBox.Height = 0;
                    //at least the same width as the textbox
                    _listBox.Width = cmbMenuName.Width;
                    //  cmbMenuName.Focus();
                    using (Graphics graphics = _listBox.CreateGraphics())
                    {
                        for (int i = 0; i < _listBox.Items.Count; i++)
                        {
                            _listBox.Height += _listBox.GetItemHeight(i);
                            // it item width is larger than the current one
                            // set it to the new max item width
                            // GetItemRectangle does not work for me
                            // we add a little extra space by using '_'
                            int itemWidth = (int)graphics.MeasureString(((String)_listBox.Items[i]) + "_", _listBox.Font).Width;
                            _listBox.Width = (_listBox.Width < itemWidth) ? itemWidth : _listBox.Width;
                        }
                    }
                }
                else
                {
                    HideListBox();
                }
            }
            else
            {
                HideListBox();
            }
        }
    }


    private void ShowListBox()
    {
        //display the listbox just below the textbox
        if (!_isAdded)
        {
            this.Controls.Add(_listBox);
            _listBox.Left = cmbMenuName.Left;
            _listBox.Top = cmbMenuName.Top + cmbMenuName.Height;
            _isAdded = true;
        }
        _listBox.Visible = true;
    }



    private String GetWord()
    {
        //get the current word (useful when there is more than one on the textbox)
        String text = cmbMenuName.Text;
        int pos = cmbMenuName.SelectionStart;

        int posStart = text.LastIndexOf(';', (pos < 1) ? 0 : pos - 1);
        posStart = (posStart == -1) ? 0 : posStart + 1;
        int posEnd = text.IndexOf(';', pos);
        posEnd = (posEnd == -1) ? text.Length : posEnd;

        int length = ((posEnd - posStart) < 0) ? 0 : posEnd - posStart;

        return text.Substring(posStart, length);
    }

    private void InsertWord(String newTag)
    {
        //add the new selection to the textbox
        String text = cmbMenuName.Text;
        int pos = cmbMenuName.SelectionStart;

        int posStart = text.LastIndexOf(';', (pos < 1) ? 0 : pos - 1);
        posStart = (posStart == -1) ? 0 : posStart + 1;
        int posEnd = text.IndexOf(';', pos);

        String firstPart = text.Substring(0, posStart) + newTag;
        String updatedText = firstPart + ((posEnd == -1) ? "" : text.Substring(posEnd, text.Length - posEnd));


        cmbMenuName.Text = updatedText;
        cmbMenuName.SelectionStart = firstPart.Length;
    }

    private void cmbMenuName_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {


        if ((e.KeyCode == Keys.Tab) && (_listBox.Visible))
        {
            InsertWord((String)_listBox.SelectedItem);
            HideListBox();
            _formerValue = cmbMenuName.Text;
        }
    }

    private void cmbMenuName_KeyDown_1(object sender, KeyEventArgs e)
    {
        e.Handled = true;
    }

答案 1 :(得分:0)

您也可以参考this link。它在c ++中使用了一些事件处理程序到toolstripcombobox。 Toolstripcombobox在某种程度上类似于组合框,因为它只是从组合框和c ++中继承而来.net中的c#似乎是相似的,因此你不会在理解代码概念时遇到太多问题。