Comment puis-je déterminer si une fenêtre WPF est modale?

Quel est le moyen le plus simple de savoir si une fenêtre est ouverte modalement ou non?

CLARIFIACTION: J'ouvre une fenêtre appelant

myWindow.ShowDialog();

J'ai un pied de page avec un bouton " OK " et "Annuler" que je veux seulement montrer si la fenêtre est ouverte modalement. Maintenant, je me rends compte que je peux définir une propriété en faisant ceci:

myWindow.IsModal = true;
myWindow.ShowDialog();

Mais je veux la fenêtre, c'est soi-même de faire cette détermination. Je veux vérifier dans l'événement "chargé" de la fenêtre si oui ou non il est modal.

Mise à jour La propriété "IsModal" n'existe pas en fait dans une fenêtre WPF. C'est une propriété que j'ai créé. ShowDialog () bloque le thread courant. Je suppose que je peux déterminer si la fenêtre est ouverte via ShowDialog () en vérifiant si le thread actuel est bloqué. Comment pourrais-je aller sur le faire?

24
demandé sur Micah 2008-12-15 19:31:35

7 réponses

Depuis http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c95f1acb-5dee-4670-b779-b07b06afafff/

"Système.Windows.Interop.ComponentDispatcher.IsThreadModal peut vous dire si le thread appelant exécute actuellement un HWND modal."

28
répondu Nash 2009-03-12 10:18:15

Il y a un champ privé _showingAsDialog chaque fois qu'une fenêtre WPF est une boîte de dialogue modale. Vous pouvez obtenir cette valeur via la réflexion et l'incorporer dans une méthode d'extension:

public static bool IsModal(this Window window)
{
    return (bool)typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(window);
}

La valeur est définie sur true lorsque la fenêtre est affichée en tant que modal (ShowDialog) et définie sur false une fois la fenêtre fermée.

28
répondu CMerat 2014-07-15 21:06:44

Ok, depuis que ma dernière idée a été rejetée, Je l'ai prouvé. cela fonctionne - et je l'ai testé dans une nouvelle application WPF, donc je sais que cela fonctionne:

Dans l'événement chargé de ma fenêtre principale (Window1), j'ai fait:

Dim frm As New Window2
frm.ShowDialog()

Dans Mon Window2, j'ai ombré la méthode ShowDialog ()

Private _IsModal As Boolean = False 'This will be changed in the IsModal method

Public Property IsModal() As Boolean
  Get
    Return _IsModal
  End Get
  Set(ByVal value As Boolean)
    _IsModal = value
  End Set
End Property

Public Shadows Sub ShowDialog()
  IsModal = True
  MyBase.ShowDialog()
End Sub

Dans mon événement chargé, j'ai ensuite déclenché une boîte de message pour m'assurer que la propriété IsModal a été changée de False à True et qu'elle me donne True, donc je sais Qu'IsModal a été défini. MyBase.ShowDialog () force alors la base classe à charger en tant que Modal. Shadows nous permet de remplacer le comportement par défaut même si la méthode ShowDialog() n'a pas été déclarée comme pouvant être remplacée.

Bien qu'il ne "détermine pas" lui-même, il ne vous oblige pas à transmettre une valeur booléenne de l'extérieur, et ne vous oblige pas à définir L'IsModal de l'extérieur, il le définit à l'intérieur de lui-même, il est accessible de l'extérieur si vous avez choisi de l'utiliser de cette façon. Il définit la valeur uniquement si elle est chargée en utilisant la méthode ShowDialog () et non si vous utilisez la méthode Show (). Je doute que vous trouverez une méthode beaucoup plus simple de le faire.

3
répondu BenAlabaster 2008-12-15 17:52:10

Voici un fragment de convertisseur qui est utile pour masquer des éléments lorsque la fenêtre est appelée par la méthode ShowDialog:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Window window = value as Window;
        if (window != null)
        {               
            var showingAsDialogFieldInfo = typeof(System.Windows.Window).GetField("_showingAsDialog",
                BindingFlags.NonPublic | BindingFlags.Instance);
            if ((bool) showingAsDialogFieldInfo.GetValue(window) == false)
            {
                return Visibility.Visible;
            }
        }
        return Visibility.Hidden;
    }
2
répondu Pluck 2016-03-24 07:38:57

En utilisant L'automatisation de L'interface utilisateur dans Windows, j'ai trouvé quelque chose comme ceci:

void Window2_Loaded(object sender, RoutedEventArgs e)
{
    var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    var el = AutomationElement.FromHandle(hwnd);

    Object oPattern = null;

    if (el.TryGetCurrentPattern(WindowPattern.Pattern, out oPattern))
    {
        var pattern = oPattern as WindowPattern;

        this.Title = pattern.Current.IsModal.ToString();
    }
}

Mais cela ne semble pas fonctionner. Il y a une propriété IsModal http://msdn.microsoft.com/en-us/library/system.windows.automation.provider.iwindowprovider.ismodal.aspx il doit y avoir un moyen approprié d'obtenir AutomationElement pour la fenêtre et de vérifier si la propriété IsModal est vraie via Automation.

0
répondu huseyint 2008-12-15 17:18:43

Une fenêtre modale arrête le traitement jusqu'à ce qu'elle soit fermée.

Cet exemple montre l'affichage d'une fenêtre non modale

dim f as myWindow
f.show
someOtherMethod()

Dans cet exemple, someOtherMethod s'exécute immédiatement après le lancement de la fenêtre.

Cet exemple montre l'affichage d'un modal:

dim f as myWindow
f.showDialog
someOtherMethod()

Dans cet exemple, someOtherMethod() ne s'exécutera pas tant que la méthode ShowDialog ne sera pas retournée (ce qui signifie que la fenêtre modale a été fermée)

Modifier en raison d'une clarification: Remplacez le ShowDialog et passez dans un booléen.

dim f as MyWindow
f.ShowDialog(true)

, Puis dans la fenêtre

Public Function Shadows ShowDialog(myVar as boolean) As Boolean
    if myVar then ShowButtons()
    return mybase.ShowDialog()
End Function 
0
répondu Stephen Wrighton 2008-12-15 17:26:19

Serait-il possible de vérifier le parent de la fenêtre pour voir si elle est désactivée? Je ne suis pas sûr si cela peut être fait via des API WPF ou non, mais si rien d'autre, vous pouvez obtenir le HWND de la fenêtre WPF, obtenir son parent via Win32 P/Invoke (ou autre), puis vérifier s'il est désactivé ou non.

Certainement pas une méthode propre, mais il semble que cela pourrait fonctionner.

-2
répondu Andy 2008-12-15 17:50:19