我怎样才能动态改变在C#组合框或文本框自动完成项目? [英] How can I dynamically change auto complete entries in a C# combobox or textbox?

查看:441
本文介绍了我怎样才能动态改变在C#组合框或文本框自动完成项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中的组合框,我想使用它自动完成的建议,但是我希望能够改变自动完成条目,用户类型,因为可能的有效项过于众多来填充 AutoCompleteStringCollection 启动。

I have a combobox in C# and I want to use auto complete suggestions with it, however I want to be able to change the auto complete entries as the user types, because the possible valid entries are far too numerous to populate the AutoCompleteStringCollection at startup.

作为一个例子,假设我让一个名称的用户类型。我有可能第一名称的列表(乔,约翰)和姓氏列表(布洛格斯,史密斯),但是如果我每一千,那么这将是一个万种可能的字符串 - 太多放在自动完成条目。所以最初我想刚才的名字作为建议(乔,约翰),然后一旦用户输入的第一个名字,(乔),我想删除现有的自动完成条目和替换他们由所选择的第一个名字后面可能的姓氏(李四,张三)的一组新的。为了做到这一点,我尝试以下code:

As an example, suppose I'm letting the user type in a name. I have a list of possible first names ("Joe", "John") and a list of surnames ("Bloggs", "Smith"), but if I have a thousand of each, then that would be a million possible strings - too many to put in the auto complete entries. So initially I want to have just the first names as suggestions ("Joe", "John") , and then once the user has typed the first name, ("Joe"), I want to remove the existing auto complete entries and replace them with a new set consisting of the chosen first name followed by the possible surnames ("Joe Bloggs", "Joe Smith"). In order to do this, I tried the following code:

void InitializeComboBox()
{
    ComboName.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
    ComboName.AutoCompleteSource = AutoCompleteSource.CustomSource;
    ComboName.AutoCompleteCustomSource = new AutoCompleteStringCollection();
    ComboName.TextChanged += new EventHandler( ComboName_TextChanged );
}

void ComboName_TextChanged( object sender, EventArgs e )
{
    string text = this.ComboName.Text;
    string[] suggestions = GetNameSuggestions( text );

    this.ComboQuery.AutoCompleteCustomSource.Clear();
    this.ComboQuery.AutoCompleteCustomSource.AddRange( suggestions );
}

然而,这种不正常工作。看来,调用清除()会导致自动完成机制为关闭,直到下一个字符出现在组合框中,当然在下一字符出现以上code调用清除()了,所以用户实际上从未看到自动完成功能。这也导致了组合框的全部内容,成为选定的,所以每一个关键preSS之间你必须取消现有的文本,这使得它无法使用。如果我删除调用清除(),则自动完成的作品,但似乎那么的AddRange()调用没有任何效果,因为我加入了新的建议做没有出现在自动完成下拉列表。

However, this does not work properly. It seems that the call to Clear() causes the auto complete mechanism to "turn off" until the next character appears in the combo box, but of course when the next character appears the above code calls Clear() again, so the user never actually sees the auto complete functionality. It also causes the entire contents of the combo box to become selected, so between every keypress you have to deselect the existing text, which makes it unusable. If I remove the call to Clear() then the auto complete works, but it seems that then the AddRange() call has no effect, because the new suggestions that I add do not appear in the auto complete dropdown.

我一直在寻找一个解决这个,见过各种事情的建议,但我不能让任何人的工作 - 无论是自动完成的功能出现禁用,或者新的字符串不会出现。这里是我试过的事情的清单:

I have been searching for a solution to this, and seen various things suggested, but I cannot get any of them to work - either the auto complete functionality appears disabled, or new strings do not appear. Here is a list of things I have tried:


  • 电话的BeginUpdate()更换琴弦之前和 EndUpdate()之后。

  • 电话删除()上的所有现有的字符串,而不是清除()。

  • 从组合框清除文本,而我更新的字符串,并将其重新添加之后。

  • 设置 AutoCompleteMode 为无,而我改变字符串,并设置回SuggestAppend之后。

  • 挂钩 TextUpdate 键preSS 事件,而不是框TextChanged

  • 更换现有的 AutoCompleteCustomSource 用新的 AutoCompleteStringCollection 各一次。

  • Calling BeginUpdate() before changing the strings and EndUpdate() afterward.
  • Calling Remove() on all the existing strings instead of Clear().
  • Clearing the text from the combobox while I update the strings, and adding it back afterward.
  • Setting the AutoCompleteMode to "None" while I change the strings, and setting it back to "SuggestAppend" afterwards.
  • Hooking theTextUpdate or KeyPress event instead of TextChanged.
  • Replacing the existing AutoCompleteCustomSource with a new AutoCompleteStringCollection each time.

的这些无帮助,即使是在各种组合。 斯宾塞建议我尝试重写组合框函数获取列表字符串的汽车完全使用。使用反射我发现一对夫妇在该看好的组合框类方法 - GetStringsForAutoComplete() SetAutoComplete(),但它们都是私人,所以我无法从派生类中访问它们。我不能采取任何进一步的。

None of these helped, even in various combinations. Spence suggested that I try overriding the ComboBox function that gets the list of strings to use in auto complete. Using a reflector I found a couple of methods in the ComboBox class that look promising - GetStringsForAutoComplete() and SetAutoComplete(), but they are both private so I can't access them from a derived class. I couldn't take that any further.

我试过更换组合框文本框,因为自动完整的接口是相同的,而且我发现该行为是稍有不同。随着文本框它似乎更好地工作,在汽车的附加部分全集正常,但建议部分没有 - 意见箱短暂闪烁的生命,但然后立即消失。

I tried replacing the ComboBox with a TextBox, because the auto complete interface is the same, and I found that the behaviour is slightly different. With the TextBox it appears to work better, in that the Append part of the auto complete works properly, but the Suggest part doesn't - the suggestion box briefly flashes to life but then immediately disappears.

所以,我想,当我设置好吧,我会生活在没有提示功能,只需使用附加,而不是,但是 AutoCompleteMode 来追加,我得到一个访问违反异常。同样的事情发生与建议 - 不抛出异常的唯一方式是 SuggestAppend ,即使推荐部分不那么正确的行为。

So I thought "Okay, I'll live without the Suggest functionality and just use Append instead", however when I set the AutoCompleteMode to Append, I get an access violation exception. The same thing happens with Suggest - the only mode that doesn't throw exceptions is SuggestAppend, even though the Suggest part doesn't then behave correctly.

我认为这应该是不可能的使用C#时获得访问冲突异常管理code。 阿夫拉姆建议我用锁定来解决这个问题,但我不知道我应该锁定 - 唯一的事情,有SyncRoot上部件的 AutoCompleteStringCollection 和锁定,这并不prevent访问冲突异常。我也试过锁定组合框文本框,但这并没有帮助。据我了解,仅锁定prevents其他的锁,因此,如果底层code未使用锁,然后我用它不会使任何区别。

I thought that it was supposed to be impossible to get access violation exceptions when using C# managed code. Avram suggested I use "lock" to fix this, but I don't know what I should lock - the only thing that has a SyncRoot member is the AutoCompleteStringCollection, and locking that doesn't prevent the access violation exceptions. I also tried locking the ComboBox or TextBox, but that didn't help either. As I understand it, lock only prevents other locks, so if the underlying code isn't using lock then my using it won't make any difference.

这一切的结果是,我目前还不能使用文本框组合框动态汽车完成。没有人有任何见解,我怎么能做到这一点?

The upshot of all this is that I can't currently use a TextBox or a ComboBox with dynamic auto complete. Does anyone have any insights into how I could achieve this?

我还没有得到这个工作,但我已经发现了一些。也许一些这会激发别人拿出一个解决方案。

I still haven't got this working, but I have found out some more. Maybe some of this will inspire someone else to come up with a solution.

我试过更换组合框文本框,因为自动完整的接口是相同的,而且我发现该行为是稍有不同。随着文本框它似乎更好地工作,在汽车的附加部分全集正常,但建议部分没有 - 意见箱短暂闪烁的生命,但然后立即消失。

I tried replacing the ComboBox with a TextBox, because the auto complete interface is the same, and I found that the behaviour is slightly different. With the TextBox it appears to work better, in that the Append part of the auto complete works properly, but the Suggest part doesn't - the suggestion box briefly flashes to life but then immediately disappears.

所以,我想,当我设置好吧,我会生活在没有提示功能,只需使用附加,而不是,然而在 AutoCompleteMode 来追加,我得到一个访问违反异常。同样的事情发生与建议 - 不抛出异常的唯一方式是 SuggestAppend ,即使推荐部分不那么正确的行为。

So I thought "Okay, I'll live without the Suggest functionality and just use Append instead," however when I set the AutoCompleteMode to Append, I get an access violation exception. The same thing happens with Suggest - the only mode that doesn't throw exceptions is SuggestAppend, even though the Suggest part doesn't then behave correctly.

我认为这应该是不可能用C#托管code时获得访问冲突异常,但无论如何,其结果是,我目前还不能使用文本框组合框与任何一种动态自动完成的。没有人有任何见解,我怎么能做到这一点?

I thought that it was supposed to be impossible to get access violation exceptions when using C# managed code, but anyway, the upshot is that I can't currently use a TextBox or a ComboBox with any kind of dynamic auto complete. Does anyone have any insights into how I could achieve this?

尝试各种其他的东西,如改变工作线程的自动完成,并且使用后的BeginInvoke()模拟PostMessage的()类型的行为,我终于放弃了,只是使用一个列表框来实现我自己的自动完成下拉列表。它比更为敏感内置的一个,我花了更少的时间做的比我试图让内置一上班,所以其他人谁希望这种行为的教训是 - 你可能会更好过自己实现它。

After trying various other things such as changing the autocomplete in a worker thread, and using BeginInvoke() to simulate PostMessage() type behaviour, I finally gave up and just implemented my own auto complete dropdown using a list box. It's much more responsive than the built-in one, and I spent less time doing that than I did trying to get the built-in one to work, so the lesson for anyone else who wants this behaviour is - you're probably better off implementing it yourself.

推荐答案

我有同样的问题,并发现了一个非常简单的解决方法。由于这里所有的人,我找不到任何手段来控制组件的行为去,所以我必须接受它。

I had the same problem, and found an extremely simple workaround. As everybody else here, I couldn't find any means to control de behaviour of the component, so I had to accept it.

自然的行为是:你不能每一次动态填充列表中的用户类型到文本框中。你必须一次填充它,然后自动完成机制取得控制权。结论是:你应该填充AutoCompleteCustomSource在你数据库中的每个可能的入口,使其工作,因为我们希望

The natural behaviour is: you can't dynamically populate the list every time the user types into the text box. You have to populate it once, and then the AutoComplete mechanism takes control. The conclusion is: you should populate the AutoCompleteCustomSource with every possible entry in you database to make it work as we want.

当然,如果你有百万条记录来填充列表,这是不可行的。在数据传输和自动完成机制本身不会允许你这样做。

Of course this is not viable if you have millions of records to populate the list. Performance issues in data transfer and the AutoComplete mechanism itself will not allow you to do that.

该折衷的解决办法,我发现是:(在我的情况3)文本长度达到确切的N个字符每一次动态填充AutoCompleteCustomSource。这个工作是因为复杂度大大降低。这是从符合这些最初的3字符数据库提取的记录数量是足够小,以避免任何性能问题。

The compromise solution I found was: dynamically populate the AutoCompleteCustomSource every time that the Text length reaches exactly N chars (3 in my case). This worked because complexity was drastically reduced. The number of records that are fetched from the database that match these 3 initial chars was small enough to avoid any performance issues.

的主要缺点是:用户不会presented自动完成列表,直到他们键入N个字符。但似乎用户并不真正指望一个有意义的自动完成列表3个字符被键入之前。

The major drawback is: users will not be presented the AutoComplete list until they type the N-th char. But it seems like users don't really expect a meaningful AutoComplete list before 3 chars are typed.

希望这有助于。

这篇关于我怎样才能动态改变在C#组合框或文本框自动完成项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆