Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有数据库驱动的自动完成功能的WinForms(C#)输入字段_C#_Winforms_Combobox_Autocomplete_Textchanged - Fatal编程技术网

带有数据库驱动的自动完成功能的WinForms(C#)输入字段

带有数据库驱动的自动完成功能的WinForms(C#)输入字段,c#,winforms,combobox,autocomplete,textchanged,C#,Winforms,Combobox,Autocomplete,Textchanged,我正在尝试创建一个具有自动完成功能的文本输入字段。可用选项的列表非常庞大(50000+个),需要在TextChanged上查询(输入前3个字符后) 我有一个使用TextBox的99%有效解决方案,在TextChanged事件中将AutoCompleteCustomSource设置为我的新AutoCompleteTestringCollection,但由于底层AutoComplete实现中有一个众所周知的错误,这会导致偶尔出现内存访问冲突 说“不要在关键事件期间动态修改自动完成候选列表” 几条这样

我正在尝试创建一个具有自动完成功能的文本输入字段。可用选项的列表非常庞大(50000+个),需要在TextChanged上查询(输入前3个字符后)

我有一个使用TextBox的99%有效解决方案,在TextChanged事件中将AutoCompleteCustomSource设置为我的新AutoCompleteTestringCollection,但由于底层AutoComplete实现中有一个众所周知的错误,这会导致偶尔出现内存访问冲突

说“不要在关键事件期间动态修改自动完成候选列表”

几条这样的线索:

这些线程对如何防止异常有一些建议,但似乎没有什么能完全消除它们,所以我正在寻找一种替代方法。已尝试切换到基于组合框的解决方案,但无法使其按我想要的方式运行

  • 在用户键入第三个字符后,我更新组合框的数据源,但第一个项目会自动选中。用户无法继续键入名称的其余部分

  • 在用户单击三角形展开列表之前,组合框项不可见

  • 如果用户选择他们输入的文本并开始键入,我将DataSource设置为null以删除建议列表。这样做会将光标放在文本的开头,因此它们的字符显示顺序完全错误

我的看法是:

    public event EventHandler SearchTextChanged;
    public event EventHandler InstrumentSelected;

    public Instrument CurrentInstrument
    {
        get { return comboBoxQuickSearch.SelectedItem as Instrument; }
    }

    public IEnumerable<Instrument> Suggestions
    {
        get { return comboBoxQuickSearch.DataSource as IEnumerable<Instrument>; }
        set
        {
            comboBoxQuickSearch.DataSource = value;
            comboBoxQuickSearch.DisplayMember = "Name";
        }
    }

    public string SearchText
    {
        get { return comboBoxQuickSearch.Text; }
    }

    private void comboBoxQuickSearch_TextChanged(object sender, EventArgs e)
    {
        if (SearchTextChanged != null)
        {
            SearchTextChanged(sender, e);
        }
    }

    private void comboBoxQuickSearch_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter && InstrumentSelected != null)
        {
            InstrumentSelected(sender, e);
        }
    }
公共事件事件处理程序SearchTextChanged;
已选择公共事件事件处理程序;
公共仪器
{
获取{return comboxQuickSearch.SelectedItem as Instrument;}
}
公众的无数建议
{
获取{return comboBoxQuickSearch.DataSource作为IEnumerable;}
设置
{
comboBoxQuickSearch.DataSource=值;
comboBoxQuickSearch.DisplayMember=“Name”;
}
}
公共字符串搜索文本
{
获取{return comboBoxQuickSearch.Text;}
}
private void ComboxQuickSearch_TextChanged(对象发送方,事件参数e)
{
如果(SearchTextChanged!=null)
{
SearchTextChanged(发件人,e);
}
}
private void ComboxQuickSearch_KeyDown(对象发送方,KeyEventArgs e)
{
如果(e.KeyCode==Keys.Enter&&InstrumentSelected!=null)
{
所选设备(发送方,e);
}
}
我的演示者:

    private void SearchTextChanged(object sender, EventArgs e)
    {
        lock (searchLock)
        {
            // Do not update list of suggestions if:
            // 1) an instrument has already been selected
            //    (the user may be scrolling through suggestion list)
            // 2) a search has taken place within the last MIN_SEARCH_INTERVAL
            if (DateTime.Now - quickSearchTimeStamp < minimumSearchInterval
                || (view.Suggestions != null && view.Suggestions.Any(i => i.Name == view.SearchText)))
            {
                return;
            }

            string searchText = view.SearchText.Trim();
            if (searchText.Length < SEARCH_PREFIX_LENGTH)
            {
                // Do not show suggestions
                view.Suggestions = null;
                searchAgain = false;
            }
            // If the prefix has been entered or changed,
            // or another search is needed to display the full sublist
            else if (searchText.Length == SEARCH_PREFIX_LENGTH
                  || searchText.Substring(0, SEARCH_PREFIX_LENGTH) != searchTextPrefix
                  || searchAgain)
            {
                // Record the current time and prefix
                quickSearchTimeStamp = DateTime.Now;
                searchTextPrefix = searchText.Substring(0, SEARCH_PREFIX_LENGTH);

                // Query matches from DB
                IList<Instrument> matches = QueryMatches(searchText);

                // Update suggestions
                view.Suggestions = matches;

                // If a large number of results was received, search again on the next chararacter
                // This ensures the full match list is presented
                searchAgain = matches.Count() > MAX_RESULTS;
            }
        }
    }
private void SearchTextChanged(对象发送方,事件参数e)
{
锁(搜索锁)
{
//如果出现以下情况,请勿更新建议列表:
//1)已选择一种仪器
//(用户可能正在滚动浏览建议列表)
//2)在上一个最小搜索间隔内进行了搜索
如果(DateTime.Now-quickSearchTimeStamp<最小搜索间隔
||(view.Suggestions!=null&&view.Suggestions.Any(i=>i.Name==view.SearchText)))
{
返回;
}
string searchText=view.searchText.Trim();
if(searchText.Length<搜索前缀长度)
{
//不要给出建议
view.Suggestions=null;
再次搜索=假;
}
//如果输入或更改了前缀,
//或者需要另一次搜索来显示完整的子列表
else if(searchText.Length==搜索前缀长度
||searchText.Substring(0,搜索前缀长度)!=searchTextPrefix
||(再次搜索)
{
//记录当前时间和前缀
quickSearchTimeStamp=DateTime.Now;
searchTextPrefix=searchText.Substring(0,搜索前缀长度);
//从数据库查询匹配项
IList matches=查询匹配(searchText);
//更新建议
查看。建议=匹配;
//如果收到大量结果,请再次搜索下一个字符
//这样可以确保显示完整的匹配列表
searchreach=matches.Count()>MAX\u结果;
}
}
}
(SearchReach位是TextBox实现留下的,其中AutoCompleteCustomSource如果包含太多项,则不会始终显示完整列表。)

鉴于我需要查询文本更改上的建议,我是否可以让组合框按我所希望的方式工作,根据用户类型提供建议


是否有其他控件组合可用于更好的用户体验,例如ListBox?

在处理textchanged事件后尝试更新。(即添加时间延迟)感谢您的回复。你认为最可靠的方法是什么?有趣的是,在TextChanged之后异步更新AutoCompleteDataSource不会导致建议列表“下拉”到文本框下方。