C#winforms组合框动态自动完成

alg*_*eat 23 c# combobox autocomplete dynamic winforms

我的问题与此问题类似:如何在C#组合框或文本框中动态更改自动完成条目? 但我仍然没有找到解决方案.

问题简述:

我有一个ComboBox和大量的记录显示在其中.当用户开始输入时,我想加载以输入文本开头的记录,并为用户提供自动完成功能.如上面的主题所述,我无法加载它们?omboBox_TextChanged因为我总是覆盖以前的结果而从未看到它们.

我可以只使用它ComboBox吗?(不TextBoxListBox)

我用这个设置:

?omboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
?omboBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
Run Code Online (Sandbox Code Playgroud)

小智 36

我最近也遇到过这些要求.我设置了下面的属性而没有编写它的工作代码.看看这是否对你有所帮助.

在此输入图像描述

  • 我喜欢这个解决方案。我所做的一项更改是使用 DropDownStyle=DropDown 以便用户可以开始输入自由格式,然后它会从列表中自动完成。 (6认同)

alg*_*eat 19

这是我的最终解决方案.它适用于大量数据.我Timer用来确保用户想要找到当前值.它看起来很复杂,但事实并非如此.感谢Max Lambertini的想法.

        private bool _canUpdate = true; 

        private bool _needUpdate = false;       

        //If text has been changed then start timer
        //If the user doesn't change text while the timer runs then start search
        private void combobox1_TextChanged(object sender, EventArgs e)
        {
            if (_needUpdate)
            {
                if (_canUpdate)
                {
                    _canUpdate = false;
                    UpdateData();                   
                }
                else
                {
                    RestartTimer();
                }
            }
        }

        private void UpdateData()
        {
            if (combobox1.Text.Length > 1)
            {
                List<string> searchData = Search.GetData(combobox1.Text);
                HandleTextChanged(searchData);
            }
        }       

        //If an item was selected don't start new search
        private void combobox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            _needUpdate = false;
        }

        //Update data only when the user (not program) change something
        private void combobox1_TextUpdate(object sender, EventArgs e)
        {
            _needUpdate = true;
        }

        //While timer is running don't start search
        //timer1.Interval = 1500;
        private void RestartTimer()
        {
            timer1.Stop();
            _canUpdate = false;
            timer1.Start();
        }

        //Update data when timer stops
        private void timer1_Tick(object sender, EventArgs e)
        {
            _canUpdate = true;
            timer1.Stop();
            UpdateData();
        }

        //Update combobox with new data
        private void HandleTextChanged(List<string> dataSource)
        {
            var text = combobox1.Text;

            if (dataSource.Count() > 0)
            {
                combobox1.DataSource = dataSource;  

                var sText = combobox1.Items[0].ToString();
                combobox1.SelectionStart = text.Length;
                combobox1.SelectionLength = sText.Length - text.Length;
                combobox1.DroppedDown = true;


                return;
            }
            else
            {
                combobox1.DroppedDown = false;
                combobox1.SelectionStart = text.Length;
            }
        }
Run Code Online (Sandbox Code Playgroud)

这个解决方案不是很酷.因此,如果有人有其他解决方案,请与我分享.

  • 如果 - 像我一样 - 你发现使用"combobox1.DroppedDown = true"会导致鼠标光标消失,在它之后添加"Cursor.Current = Cursors.Default". (5认同)

Max*_*ini 9

是的,你肯定可以...但它需要一些工作才能使它无缝地工作.这是我提出的一些代码.请记住,它使用combobox的自动完成功能,如果你用它来筛选很多物品,它可能会很慢......

string[] data = new string[] {
    "Absecon","Abstracta","Abundantia","Academia","Acadiau","Acamas",
    "Ackerman","Ackley","Ackworth","Acomita","Aconcagua","Acton","Acushnet",
    "Acworth","Ada","Ada","Adair","Adairs","Adair","Adak","Adalberta","Adamkrafft",
    "Adams"

};
public Form1()
{
    InitializeComponent();
}

private void comboBox1_TextChanged(object sender, EventArgs e)
{
    HandleTextChanged();
}

private void HandleTextChanged()
{
    var txt = comboBox1.Text;
    var list = from d in data
               where d.ToUpper().StartsWith(comboBox1.Text.ToUpper())
               select d;
    if (list.Count() > 0)
    {
        comboBox1.DataSource = list.ToList();
        //comboBox1.SelectedIndex = 0;
        var sText = comboBox1.Items[0].ToString();
        comboBox1.SelectionStart = txt.Length;
        comboBox1.SelectionLength = sText.Length - txt.Length;
        comboBox1.DroppedDown = true;
        return;
    }
    else
    {
        comboBox1.DroppedDown = false;
        comboBox1.SelectionStart = txt.Length;
    }
}

private void comboBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Back)
    {
        int sStart = comboBox1.SelectionStart;
        if (sStart > 0)
        {
            sStart--;
            if (sStart == 0)
            {
                comboBox1.Text = "";
            }
            else
            {
                comboBox1.Text = comboBox1.Text.Substring(0, sStart);
            }
        }
        e.Handled = true;
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 9

我写了这样的东西....

private void frmMain_Load(object sender, EventArgs e)
{
    cboFromCurrency.Items.Clear();
    cboComboBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
    cboComboBox1.AutoCompleteSource = AutoCompleteSource.ListItems;
    // Load data in comboBox => cboComboBox1.DataSource = .....
    // Other things
}

private void cboComboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    cboComboBox1.DroppedDown = false;
}
Run Code Online (Sandbox Code Playgroud)

这就是全部(Y)