【发布时间】:2012-02-05 11:09:09
【问题描述】:
我的客户希望在应用程序的客户表单中有一个文本框,它为开始的街道名称提供适用的结尾。他开始输入街道名称,文本框提供街道列表,这些街道以他在文本框中输入的字符序列开头。
我对自己说:没关系,文本框有 AutoCompleteCustomSource 属性,即使常见的街道名称列表比开始时预填充的要长,我也可以通过查询访问数据库,填充AutoCompleteStringCollection 并将其显示给用户。
现在事情是这样的:如果我在每次按键/按键时都填充列表,程序会崩溃并抛出 AccessViolationException。
我发现这是因为: 控件在显示自动完成列表的同时被修改,导致崩溃。
当您刷新自动完成列表时,将使用新指针重新创建控件。键盘和鼠标事件(KeyPress、MouseOver、MouseLeave、MouseHover)尝试引用旧控件的指针,这些指针现在在内存中无效,从而导致发生内存访问冲突。
一旦在窗口上设置了 AutoComplete 候选列表对象,底层的 AutoComplete 实现就不允许更改它。为了允许更改列表,WinForms 会破坏 Edit 控件或 ComboBox 并重新创建它。如果底层控件在 AutoComplete 窗口仍在使用时被销毁,则会导致异常。
我在MSDN 上读到了这个,他们的决议:
不要在关键事件期间动态修改自动完成候选列表。
我也尝试了this线程中的所有内容
那么,如果我坚持逐个按键提供适用的街道名称,我该怎么做呢?
注意:我知道您可以通过创建自定义控件等来做到这一点,但可以仅通过纯编码向导来完成吗?
【问题讨论】:
-
为什么不从数据库中填充一次列表,包括每个项?这可行吗?
-
“制作一个 WPF 控件并在你的 WINFORMs 项目中使用它”..
-
@minitech 好吧,我想这是一种方法,但是每次客户想要检查客户时加载 10,000 行...我不知道我对此有何感受...我可能不得不向这里的一些专业人士询问有关加载这么多数据的问题。客户可能甚至不想编辑该框,只需复制街道名称或其他内容。作为一种临时措施,它可能会起作用,但有什么方法可以按照我们最初想要的方式进行吗?
-
@Andris:好吧,试试看它有多快......我也认为你可以将它绑定到数据库并让它自己完成,但我无法尝试现在。
标签: c# .net vb.net exception access-violation