0
votes

I have a modal form with a single instance of the built-in .NET 2.0 tab control. The tab control has several pages, and on one of them is a combo box that isn't populated until the user activates it for the first time. When that happens, I handle the DropDown event and run a process that takes several seconds, then I add the items returned by that process to the combo box.

It works fine, except right after the list portion of the combo box is dropped down, it immediately closes as if some other control took the focus. I've narrowed it down to the fact that there is a tab control on the form, and the process that retrieves items for the combo box takes more than 4 seconds. If I create a completely blank form with just the combo box, I don't see this behavior.

Needless to say, this is strange beyond belief. Any idea why the tab control would interfere with the control that currently has focus?

EDIT:

Here is the event handler code for the given combo box. Basically I'm building a list of SQL servers on the network. The thing that takes several seconds is the call to 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
1
The tab control is notorious for causing focus problems and other issues with child controls. I have never seen this particular issue, but I will try to replicate it.David Nelson
I cannot reproduce the behaviour (but it sounds from your description like it requires special circumstances), but out of curiosity; can you share with us the code in the DropDown event handler (and any other code that accesses the combo box during the execution of that handler)?Fredrik Mörk
You could try putting a breakpoint in the ComboBox's LostFocus event and inspect the StackTrace for what initiated the call. This might offer some more insight.Steve Dignan

1 Answers

0
votes

I was able to solve this problem.

I first added a breakpoint to the LostFocus event of the combo box and looked at the stack trace per Steve Dignan's suggestion, but that didn't reveal anything. One thing that is special about my form is this combo box is normally disabled and only becomes enabled when the user checks a box on the same tab page. The solution was to explicitly set the focus to the combo box when the box was checked, like so:

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

The drop-down portion of the combo box then showed normally.