tags:

views:

2975

answers:

6

What's the easiest way to figure out if a window is opened modally or not?

CLARIFIACTION: I open a window calling

myWindow.ShowDialog();

I have a footer with an "OK" & "Cancel" button that I only want to show if the window is opened modally. Now I realize I can set a property by doing this:

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

But I want the window it's self to make that determination. I want to check in the "Loaded" event of the window whether or not it is modal.

UPDATE The "IsModal" property doesn't actually exist in a WPF window. It's a property that I have created. ShowDialog() blocks the current thread. I'm guessing I can determine if the Window is opened via ShowDialog() by checking if the current thread is blocked. How would I go about doing that?

A: 

a modal window will stop processing until it is closed.

This example shows displaying a non-modal window

dim f as myWindow
f.show
someOtherMethod()

In this example, someOtherMethod runs immediately after the window is launched.

This example shows displaying a modal one:

dim f as myWindow
f.showDialog
someOtherMethod()

In this example, someOtherMethod() won't run until the ShowDialog method returns (which means that the modal window has been closed)

EDIT due to clarification: Override the ShowDialog and pass in a boolean.

dim f as MyWindow
f.ShowDialog(true)

then in the window

Public Function Shadows ShowDialog(myVar as boolean) As Boolean
    if myVar then ShowButtons()
    return mybase.ShowDialog()
End Function
Stephen Wrighton
+1 I would think this is preferred to needing to use the IsModal() property too.
BenAlabaster
+1  A: 

Okay, since my last idea got voted down, I proved it. this works - and I tested it in a new WPF application, so I know it works:

In my main Window's (Window1) Loaded event, I did:

Dim frm As New Window2
frm.ShowDialog()

In my Window2 I shadowed the ShowDialog() method

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

In my Loaded event, I then fired off a message box to make sure that the IsModal property got changed from False to True and it gives me True, so I know IsModal was set. MyBase.ShowDialog() then forces the base class to be loaded as Modal. Shadows allows us to override the default behaviour even though the ShowDialog() method wasn't declared as overridable.

While it doesn't "self determine" it doesn't require you to pass in any boolean value from outside, and doesn't require you to set the IsModal from outside, it sets it inside itself, it's accessible from outside if you so chose to use it that way. It sets the value only if it us loaded using the ShowDialog() method and not if you use the Show() method. I doubt you'll find a much simpler method of doing this.

BenAlabaster
A: 

Using UI Automation in Windows, I have come up with something like this:

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();
    }
}

But this seems not working. There is an IsModal property http://msdn.microsoft.com/en-us/library/system.windows.automation.provider.iwindowprovider.ismodal.aspx there must be a proper way to get AutomationElement for the window and check whether IsModal property of it is true via Automation.

huseyint
A: 

Would it be possible to check the window's parent to see if it is disabled? I'm not sure if this can be done via WPF APIs or not, but if nothing else you could get the HWND of the WPF window, get its parent via Win32 P/Invoke (or whatever), and then check to see if it is disabled or not.

Definitely not a clean method, but it seems like it could work.

Andy
+5  A: 

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

"System.Windows.Interop.ComponentDispatcher.IsThreadModal can tell you if the calling thread is currently running a modal hwnd."

Exactly what I was looking for. Awesome!
Micah
A: 

There's a private field _showingAsDialog whenever a WPF Window is a modal dialog. You could get that value via reflection and incorporate it in an extension method:

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

The value is set to true when the window is shown as modal (ShowDialog) and set to false once the window closes.

CMerat