一尘不染

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

c#

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

问题简述:

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

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

我使用以下设置:

сomboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
сomboBox.AutoCompleteSource = AutoCompleteSource.CustomSource;

阅读 249

收藏
2020-05-19

共1个答案

一尘不染

这是我的最终解决方案。它可以处理大量数据。我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;
            }
        }

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

2020-05-19