.net 使用tab控件时,组合框下拉列表意外关闭

.net 使用tab控件时,组合框下拉列表意外关闭,.net,vb.net,winforms,.net,Vb.net,Winforms,我有一个模态表单,其中有一个内置.NET2.0选项卡控件的实例。tab控件有几个页面,其中一个页面上有一个组合框,直到用户第一次激活它时才会填充。当这种情况发生时,我处理下拉事件并运行一个需要几秒钟的进程,然后将该进程返回的项目添加到组合框中 它工作正常,除了在下拉组合框的列表部分之后,它会立即关闭,就像其他控件占据了焦点一样。我已经将范围缩小到表单上有一个选项卡控件,并且为组合框检索项目的过程需要4秒钟以上。如果我只使用组合框创建一个完全空白的表单,我看不到这种行为 不用说,这是不可思议的。知

我有一个模态表单,其中有一个内置.NET2.0选项卡控件的实例。tab控件有几个页面,其中一个页面上有一个组合框,直到用户第一次激活它时才会填充。当这种情况发生时,我处理下拉事件并运行一个需要几秒钟的进程,然后将该进程返回的项目添加到组合框中

它工作正常,除了在下拉组合框的列表部分之后,它会立即关闭,就像其他控件占据了焦点一样。我已经将范围缩小到表单上有一个选项卡控件,并且为组合框检索项目的过程需要4秒钟以上。如果我只使用组合框创建一个完全空白的表单,我看不到这种行为

不用说,这是不可思议的。知道为什么选项卡控件会干扰当前具有焦点的控件吗

编辑:

下面是给定组合框的事件处理程序代码。基本上,我正在网络上建立一个SQL服务器列表。需要几秒钟的事情是调用GetDataSources

Private Sub cmbServer_DropDown(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmbServer.DropDown
    Dim oTable As DataTable
    Dim lstServers As List(Of String)
    Dim lstAliases As List(Of String)

    Try
        If cmbServer.Items.Count = 0 Then
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor
            oTable = System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources
            lstServers = New List(Of String)

            For Each oRow As DataRow In oTable.Rows
                If oRow("InstanceName").ToString = "" Then
                    lstServers.Add(oRow("ServerName").ToString)
                Else
                    lstServers.Add(oRow("ServerName").ToString & "\" & oRow("InstanceName").ToString)
                End If
            Next oRow

            'Retrieve any server aliases on the client and add them to the server list
            lstAliases = GetSQLServerAliases()
            If lstAliases IsNot Nothing Then
                For Each sAlias As String In lstAliases
                    lstServers.Add(sAlias)
                Next sAlias
            End If

            lstServers.Sort()
            For Each sServer As String In lstServers
                cmbServer.Items.Add(sServer)
            Next sServer
        End If
    Catch ex As Exception
        ErrHandler("frmRefreshDB", "cmbServer_DropDown", ex.Source, ex.Message, ex.InnerException)
    Finally
        System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default

        If oTable IsNot Nothing Then
            oTable.Dispose()
        End If
    End Try
End Sub

我能解决这个问题

我首先在组合框的LostFocus事件中添加了一个断点,并按照Steve Dignan的建议查看了堆栈跟踪,但这没有透露任何信息。我的表单有一个特别之处,就是这个组合框通常是禁用的,只有在用户选中同一选项卡页面上的一个框时才会启用。解决方案是在选中组合框时显式将焦点设置为组合框,如下所示:

Private Sub chkAltServer_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkAltServer.CheckedChanged
    Try
        If chkAltServer.Checked Then
            UnlockControl(cmbServer)
            cmbServer.Focus()
        Else
            LockControl(cmbServer)
        End If
    Catch ex As Exception
        ErrHandler("frmOptions", "chkAltServer_CheckedChanged", ex.Source, ex.Message, ex.InnerException)
    End Try
End Sub

组合框的下拉部分随后正常显示。

选项卡控件因引起焦点问题和子控件的其他问题而臭名昭著。我从未见过这个特殊的问题,但我会尝试复制它。我无法复制这种行为(但从你的描述听起来,它需要特殊的环境),但出于好奇;您能否与我们共享下拉事件处理程序中的代码(以及在该处理程序执行期间访问组合框的任何其他代码)?您可以尝试在组合框的LostFocus事件中放置断点,并检查StackTrace以了解是什么启动了调用。这可能会提供更多的见解。