动态改变文本框的自动完成列表导致AccessViolationException,什么建议? [英] Dynamically changing Textbox's AutoComplete List causes AccessViolationException, any advice?

查看:258
本文介绍了动态改变文本框的自动完成列表导致AccessViolationException,什么建议?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的客户希望在应用程序,它提供了适用的结局到启动街道名称的客户形式的文本框。他开始键入一个街道名称和文本框提供其与炭序列他输入到文本框中启动街道的列表。

My client wanted to have a textbox in the Customer form of the application, which offers the applicable endings to a started street name. He starts to type a street name and the textbox offers a list of streets which start with the char sequence he typed into the textbox.

我对自己说:多数民众赞成没关系,文本框有AutoCompleteCustomSource财产,即使普通的街道名称的列表将长于它可能是pre-填补开始,我可能只是打了一个数据库查询,填充一个AutoCompleteStringCollection并显示给用户。

I said to myself: thats okay, textboxes have the AutoCompleteCustomSource property and even though a list of common street names will be longer than it could be pre-filled on start, i could just hit a database with a query, populate an AutoCompleteStringCollection and show that to the user.

现在这里的东西:如果我做了列表填充上的每个按键preSS / KEYDOWN什么的,程序崩溃并引发AccessViolationException

Now here's the thing: if I make the list populate on every keypress/keydown whatever, the program crashes and throws an AccessViolationException.

我发现,这是因为: 控制是在显示自动完成列表时,在同一时间它已被修改,从而导致飞机坠毁的中间。

I've found out that that's because: The control is in the middle of showing the AutoComplete list when at the same time it is being modified, resulting in the crash.

在刷新自动完成列表,该控件重新创建新的指针。键盘和鼠标事件(主要preSS,鼠标悬停,鼠标离开,MouseHover)尝试引用旧控件的指针而现在内存无效导致内存访问冲突发生。

When you refresh the Autocomplete List, the control is recreated with new pointers. Keyboard and mouse events (KeyPress, MouseOver, MouseLeave, MouseHover) attempt to reference the old control's pointers which are now invalid in memory causing a memory access violation to occur.

底层自动完成实现不允许用于改变自动完成候选列表对象一旦已被设定在一个窗口。要允许更改列表的WinForms破坏编辑控件或组合框,并重新创建。这会导致如果底层控制被破坏,同时自动完成窗口仍然使用它的一个例外。

The underlying AutoComplete implementation does not allow for changing the AutoComplete candidate list object once it has been set on a window. To allow changing the list, WinForms destroys the Edit control or ComboBox and recreates it. This causes an exception if the underlying control is destroyed while the AutoComplete window is still use it.

我读到这在 MSDN ,它们的分辨率:

I read about this on MSDN, their resolution:

不要在关键事件修改自动完成候选名单动态。

Do not modify the AutoComplete candidate list dynamically during key events.

我也试过一切从<一个href="http://social.msdn.microsoft.com/Forums/en-EN/winforms/thread/e599b2e2-3cda-43ad-b15f-a69b4fea1a75"相对=nofollow>这个线程

所以,我怎么能做出这样的工作,如果我坚持在提供适用街道名称键preSS按键preSS?

So how could I make this work, if I insist on offering the applicable street names keypress-by-keypress?

注意:我知道,你可以通过创建一个自定义的控制,例如,做到这一点,但可以用它只是纯粹的编码巫术来完成

Note: I know that you can do this by creating a custom control and such, but can it be done with just pure coding wizardry?

推荐答案

这是我们在我们的应用程序解决此问题的方法(在这里,我们需要从可能的100,000个项目选择)是保释的自动完成功能,并使用组合框代替。

The way that we solved this issue in our application (where we need to select from possibly 100,000 items) was to bail on the auto-complete functionality and use a combobox instead.

我们使用Infragistics的组合框,但我怀疑标准的Windows一会正常工作。

We use the Infragistics combobox, but I suspect that the standard windows one would work as well.

这里的技巧是使用组合框本身,下拉模式,如自动完成列表,并填充它的用户类型。

The trick here is to use the combobox itself, in DropDown mode, as the autocomplete list and populate it as the user types.

下面是我们使用的逻辑:

Here is the logic that we use:

Private m_fOkToUpdateAutoComplete As Boolean
Private m_sLastSearchedFor As String = ""

Private Sub cboName_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles m_cboName.KeyDown
    Try
        ' Catch up and down arrows, and don't change text box if these keys are pressed.
        If e.KeyCode = Keys.Up OrElse e.KeyCode = Keys.Down Then
            m_fOkToUpdateAutoComplete = False
        Else
            m_fOkToUpdateAutoComplete = True
        End If
    Catch theException As Exception
        ' Do something with the exception
    End Try
End Sub


Private Sub cboName_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_cboName.TextChanged
    Try
        If m_fOkToUpdateAutoComplete Then
            With m_cboName
                If .Text.Length >= 4 Then
                    ' Only do a search when the first 4 characters have changed
                    If Not .Text.Substring(0, 4).Equals(m_sLastSearchedFor, StringComparison.InvariantCultureIgnoreCase) Then
                        Dim cSuggestions As StringCollection
                        Dim sError As String = ""

                        ' Record the last 4 characters we searched for
                        m_sLastSearchedFor = .Text.Substring(0, 4)

                        ' And search for those
                        ' Retrieve the suggestions from the database using like statements
                        cSuggestions = GetSuggestions(m_sLastSearchedFor, sError)
                        If cSuggestions IsNot Nothing Then
                            m_cboName.DataSource = cSuggestions
                            ' Let the list catch up. May need to do Thread.Idle here too
                            Application.DoEvents()
                        End If
                    End If
                Else
                    If Not String.IsNullOrEmpty(m_sLastSearchedFor) Then
                        ' Clear the last searched for text
                        m_sLastSearchedFor = ""
                        m_cboName.DataSource = Nothing
                    End If
                End If
            End With
        End If
    Catch theException As Exception
        ' Do something with the exception
    End Try
End Sub

由于大量项目,我们不开始搜索,直至用户输入4个字符,但是这仅仅是我们的实现。

Due to the large number of items, we don't start searching until the user has entered 4 characters, but that is just our implementation.

这篇关于动态改变文本框的自动完成列表导致AccessViolationException,什么建议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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