2010-05-27 5 views
6

J'ai une application Windows Forms sans bordure.Windows Forms et le problème ShowDialog

La fenêtre principale crée d'autres formulaires (boîtes de dialogue simples où je peux cliquer sur oui ou non) avec ShowDialog(). Chaque boîte de dialogue créée n'est pas visible dans la barre des tâches, mon application n'a qu'une seule entrée dans la barre des tâches qui focalise mon application (et si une boîte de dialogue est ouverte, celle-ci est focalisée). Si j'utilise ALT + TAB pour basculer vers toutes les fenêtres ouvertes, je ne vois qu'une seule entrée. Cependant, si la boîte de dialogue est créée alors que mon application n'a pas le focus (par exemple, l'utilisateur démarre une tâche longue, commence à travailler sur autre chose et en étant en arrière-plan, mon application affiche une boîte de dialogue Tâche accomplie ... ") et je veux revenir à mon application, les choses deviennent étranges.

  • Si je clique sur la barre des tâches pour focaliser mon application, la fenêtre principale est mise au point (pas la boîte de dialogue).
  • Je ne peux pas utiliser la fenêtre principale (car il existe toujours une boîte de dialogue modale ouverte).
  • Windows 7 ALT +TAB aperçu affiche la boîte de dialogue alors que la barre des tâches de prévisualisation affiche la fenêtre mouseover principale (dans le comportement normal aussi bien montrer la boîte de dialogue en face de la fenêtre principale).
  • La seule façon de rendre mon application utilisable à nouveau est de ALT + TAB à l'entrée et fermez la boîte de dialogue modale.
  • Si j'utilise ALT + TAB seule la boîte de dialogue est affichée au premier plan et la fenêtre principale est toujours en arrière-plan.

Existe-t-il un moyen d'empêcher cela? Je sais quoi faire, mais la plupart des clients pensent que l'application s'est bloquée car la fenêtre principale ne répond pas.

Mise à jour:

La solution est de passer la fenêtre de niveau supérieur à la méthode ShowDialog() (dans la plupart des cas et si elle est utilisée sous une forme qui serait le « ce »).

Puisque je n'ai pas voulu refactoriser tout mon code, et que tous mes formulaires héritent de "MyCustomFormBase" voici une petite solution qui fonctionne très bien.

Public Class MyCustomFormBase 

    Public Shared Property ApplicationMainForm() As Form 
     Get 
      Return _applicationMainform 
     End Get 
     Set(ByVal value As Form) 
      _applicationMainform = value 
     End Set 
    End Property 
    Private Shared _applicationMainform As Form 

    Public Shadows Function ShowDialog() As DialogResult 
     If MyCustomFormBase.ApplicationMainForm IsNot Nothing Then 
      Return MyBase.ShowDialog(MyCustomFormBase.ApplicationMainForm) 
     Else 
      Return MyBase.ShowDialog() 
     End If 
    End Function 

    Public Shadows Function ShowDialog(ByVal owner As IWin32Window) As DialogResult 
     Return MyBase.ShowDialog(owner) 
    End Function 

End Class 

Dans le constructeur de la fenêtre principale J'utilise

MyCustomFormBase.ApplicationMainForm = Me 

une fois. Il m'a aidé à refactoring une demi-journée;)

Répondre

4

Avez-vous essayé de passer une référence à la fenêtre principale à ShowDialog appels?

// assuming this code is in the main form (so "this" refers to the main form) 
DialogForm dialog = new DialogForm(); 
DialogResult result = dialog.ShowDialog(this); 

Citation du documentation of this overload:

Cette version de la méthode ShowDialog vous permet de spécifier une forme spécifique ou de contrôle qui possédera la boîte dialogue qui apparaît. Si vous utilisez la version de cette méthode qui n'a pas de paramètres , la boîte de dialogue affichée appartiendra automatiquement à la fenêtre actuellement active de votre application .

+0

J'ai probablement utilisé la méthode des milliers de fois et je n'ai jamais remarqué qu'il y avait une surcharge;) De toute façon cela fonctionne. Merci beaucoup. –

+0

+1, sans l'argument, il va essayer d'en trouver un. La fenêtre du bureau, si nécessaire. –