2009-05-22 4 views
0

J'ai un formulaire modal avec une seule instance du contrôle de tabulation .NET 2.0 intégré. Le contrôle onglet a plusieurs pages, et sur l'une d'entre elles est une zone de liste déroulante qui n'est pas remplie jusqu'à ce que l'utilisateur l'active pour la première fois. Lorsque cela se produit, je gère l'événement DropDown et exécute un processus qui prend plusieurs secondes, puis j'ajoute les éléments renvoyés par ce processus à la liste déroulante.Le menu déroulant de la zone de liste déroulante se ferme de façon inattendue lors du contrôle de tabulation

Cela fonctionne très bien, sauf juste après que la liste déroulante de la liste déroulante est tombée, elle se ferme immédiatement comme si un autre contrôle a pris le focus. Je l'ai réduit au fait qu'il existe un contrôle onglet sur le formulaire, et le processus qui récupère des éléments pour la zone de liste déroulante prend plus de 4 secondes. Si je crée un formulaire complètement vide avec seulement la zone de liste déroulante, je ne vois pas ce comportement. Inutile de dire que c'est étrange au-delà de la croyance. Une idée de pourquoi le contrôle onglet interférerait avec le contrôle qui a actuellement le focus?

EDIT:

Voici le code de gestionnaire d'événements pour la zone de liste déroulante donné. Fondamentalement, je construis une liste de serveurs SQL sur le réseau. La chose qui prend plusieurs secondes est l'appel à 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 
+0

Le contrôle de tabulation est connu pour provoquer des problèmes de mise au point et d'autres problèmes avec les contrôles enfants. Je n'ai jamais vu ce problème particulier, mais je vais essayer de le reproduire. –

+0

Je ne peux pas reproduire le comportement (mais il semble de votre description comme cela nécessite des circonstances particulières), mais par curiosité; pouvez-vous partager avec nous le code dans le gestionnaire d'événement DropDown (et tout autre code qui accède à la zone de liste déroulante lors de l'exécution de ce gestionnaire)? –

+0

Vous pouvez essayer de placer un point d'arrêt dans l'événement LostFocus de la zone de liste déroulante et d'inspecter le StackTrace pour déterminer l'origine de l'appel. Cela pourrait offrir un peu plus de perspicacité. –

Répondre

0

J'ai réussi à résoudre ce problème.

J'ai d'abord ajouté un point d'arrêt à l'événement LostFocus de la zone de liste déroulante et j'ai regardé la trace de la pile selon la suggestion de Steve Dignan, mais cela n'a rien révélé. Une chose qui est spéciale à propos de mon formulaire est que cette zone de liste déroulante est normalement désactivée et n'est activée que lorsque l'utilisateur cocher une case sur la même page à onglet. La solution était de définir explicitement le focus sur la zone de liste déroulante lorsque la case est cochée, comme ceci:

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 

La partie déroulante de la zone de liste déroulante a montré alors normalement.

Questions connexes