首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于实现“键入搜索”组合框的BackgroundWorker

用于实现“键入搜索”组合框的BackgroundWorker
EN

Stack Overflow用户
提问于 2012-08-17 17:17:25
回答 4查看 2.2K关注 0票数 2

我已经为我的combobox创建了一个代码,它可以借助存储过程(我正在使用实体框架)在Server上的一个非常大的表中搜索地址。我的存储过程返回10次点击,我的代码将搜索结果填充到组合框中。为此,我使用了BackgroundWorker。

但是现在我遇到了很大的问题:-尽管组合框里充满了我的搜索结果,但是它总是有选择的第一项。即使我只输入一个字母,整个文本也会被选中;

  • 在那之后,搜索地址就不再有效了。它只搜索这10个结果,我不知道如何解决这个问题。这是我的全部代码,这给我带来了问题: 公共字符串searchedItem = "";公共委托void DelegateUpdateComboboxSelection(ComboBox myCombo,String value,int count);BackgroundWorker m_bgworker =新BackgroundWorker();静态AutoResetEvent resetWorker =新AutoResetEvent(false);m_bgworker.WorkerSupportsCancellation = true;m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);m_bgworker.RunWorkerCompleted FillComboboxBindingList新DelegateUpdateComboboxSelection=新();void m_bgworker_RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e) { int count = (int)(( object[] )e.Result);string值= (string)((object[])e.Result)1;ComboBox myCombo = (ComboBox)((object[])e.Result)2;DelegateUpdateComboboxSelection n委托=新的RunWorkerCompletedEventArgs (this.InvokeRequired) {调用(n委托,新object[] {myCombo,value,count});返回;}{ UpdateComboSelection( myCombo,value,count);返回;}私有void UpdateComboSelection(ComboBox myCombo,String value,int count) {myCombo= comboBox9;myCombo.DataSource = m_addresses;searchedItem = myCombo.Text;if (count > 0) { myCombo.SelectionStart = value.Length;myCombo.SelectionLength = searchedItem.Length - value.Length;myCombo.DroppedDown =真;} myCombo.DroppedDown = false;myCombo.SelectionStart = value.Length;} public void FillComboboxBindingList(对象发送方,DoWorkEventArgs e) { if (m_bgworker.CancellationPending) { resetWorker.Set();e.Cancel = true;返回;}value.Length{ string值=(String)(Object[])e.Argument;结果= _vsebina.SP_searcher(value).ToList();m_addresses =新的BindingList();{ m_addresses.Add(rez);} foreach (SP_Result1 r in m_addresses.ToArray()) { if (!result.Contains(r)) { m_addresses.Remove(r);} e.Result =新object[] { rezultat.Count,vrednost,null };返回;}私有comboBox9_KeyUp(对象发送方,KeyEventArgs e) { if (e.KeyCode == Keys.Back) { int searchStart =comboBox9.选择启动;if (searchStart > 0) {searchStart-;若(searchStart == 0) { comboBox9.Text = "";} comboBox9.Text.Substring(0,searchStart + 1);} searchStart = 0;} e.Handled = true;}私有void comboBox9_Enter(对象发送方,EventArgs e) {comboBox9. sender = 0;comboBox9.Search= 0;}私有空洞comboBox9_Click(对象发送方,EventArgs e) { comboBox9.Text = "";}公共空搜索(){ if (comboBox9.Text.Length < 4) {返回;} m_bgworker (m_bgworker.IsBusy) { m_bgworker.CancelAsync();m_bgworker=新BackgroundWorker();m_bgworker.WorkerSupportsCancellation = true;m_bgworker.DoWork +=新DoWorkEventHandler(FillComboboxBindingList);新RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);}m_bgworker.RunWorkerAsync(新object[] { comboBox9.Text,comboBox9 });}

也许有人能告诉我我做错了什么。这是我第一次使用BackgroundWorker。我不知道如何以任何其他方式使用combobox实现“搜索时键入”,因为我的datatable有地址(百万条记录)。

预先感谢任何类型的帮助或代码示例。

弗拉基米尔

编辑1:好的,这是我的代码,在我使用BackGroundWorker之前。它成功了,但是搜索速度非常慢(可能需要10秒):

代码语言:javascript
复制
    private void comboBox9_TextChanged(object sender, EventArgs e)
    {
        if (comboBox9.Text.Length < 4)
        {
            return;
        }
        else
        {
            FillCombobox(comboBox9.Text, comboBox9);
        }

    }

    public void FillCombobox(string value, ComboBox myCombo)
    {
        List<spIskalnikNaslovi_Result1> result;
        result = _vsebina.spIskalnikNaslovi1(value).ToList(); 
        if (result.Count() > 0)
        {
            myCombo.DataSource = result;
            myCombo.ValueMember = "HS_MID";
            myCombo.DisplayMember = "NASLOV1";
            var searchedItem = myCombo.Items[0].ToString();
            myCombo.SelectionStart = value.Length;
            myCombo.SelectionLength = searchedItem.Length - value.Length;
            myCombo.DroppedDown = true;
        }
        else
        {
            myCombo.DroppedDown = false;
            myCombo.SelectionStart = value.Length;
        }
        return;
    }

有没有办法在没有后台工作的情况下加快这一进程?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-08-21 10:17:58

这是我没有BackGroundWorker的最后一个解决方案。它对我的大型表工作得很快,并升级为在Server上使用存储过程(如果使用实体框架)。我使用计时器来确保用户能够找到他正在搜索的值。

在这里,您可以看到我在这个站点上找到的原始解决方案(感谢Max Lambertinialgreat的想法和工作理念):

C# winforms combobox dynamic autocomplete

我的解决方案:

代码语言:javascript
复制
    private bool _canUpdate = true;
    private bool _needUpdate = false;
    List<spIskalnikNaslovi_Result1> dataFound;

    private void comboBox12_TextChanged(object sender, EventArgs e)
    {
        if (_needUpdate)
        {
            if (_canUpdate)
            {
                _canUpdate = false;
                refreshData();
            }
            else
            {
                restartTimer();
            }
        }
    }

    private void comboBox12_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Back)
        {
            int searchStart = comboBox12.SelectionStart;
            if (searchStart > 0)
            {
                searchStart--;
                if (searchStart == 0)
                {
                    comboBox12.Text = "";
                }
                else
                {
                    comboBox12.Text = comboBox12.Text.Substring(0, searchStart + 1);
                }
            }
            else 
            {
                searchStart = 0;
            }
            e.Handled = true;
        }
    }

    private void comboBox12_TextUpdate(object sender, EventArgs e)
    {
        _needUpdate = true;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        _canUpdate = true;
        timer1.Stop();
        refreshData();
    }

    private void refreshData()
    {
        if (comboBox12.Text.Length > 1)
        {
            FillCombobox(comboBox12.Text, comboBox12);
        }
    }

    private void restartTimer()
    {
        timer1.Stop();
        _canUpdate = false;
        timer1.Start();
    }


    private void FillCombobox(string value, ComboBox myCombo)
    {
        dataFound = _vsebina.spIskalnikNaslovi1(value).ToList();
        if (dataFound.Count() > 0)
        {
            myCombo.DataSource = dataFound;
            myCombo.ValueMember = "HS_MID";
            myCombo.DisplayMember = "NASLOV1";
            var searchedItem = myCombo.Items[0].ToString();
            myCombo.SelectionStart = value.Length;
            myCombo.SelectionLength = searchedItem.Length - value.Length;
            myCombo.DroppedDown = true;
            return;
        }
        else
        {
            myCombo.DroppedDown = false;
            myCombo.SelectionStart = value.Length;
            return;
        }            
    }
票数 0
EN

Stack Overflow用户

发布于 2012-08-17 18:18:05

创建一个按钮,您将调用搜索按钮,并在该按钮的click_event中调用运行后台工作人员的搜索()方法,该方法将清除组合框的key_press事件,并且它将工作,错误是key_press事件调用每一次发生搜索方法的键笔触,因此检索它。

票数 0
EN

Stack Overflow用户

发布于 2012-08-17 19:26:36

您应该在列表中获取您的项目,使用该列表填充您的组合框。

然后将AutoCompleteMode属性值设置为建议或追加或SuggestAppend,并将AutoCompleteSoucre属性值设置为ListItems。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12010219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档