When would ShowDialog() return null?
Asked Answered
P

4

37

WPF's Window.ShowDialog method returns a nullable boolean. So does CommonDialog.ShowDialog.

Now, I understand cases where these would return false (user clicked Cancel or pressed Esc), and when they would return true (code sets Window.DialogResult to true, probably in response to OK being clicked). But null?

My first thought is that clicking the title bar's Close button might return null. But the docs state (and I confirmed by testing) that the title-bar Close button is treated as a Cancel.

So when would Window.ShowDialog or CommonDialog.ShowDialog ever return null?

Plexiform answered 13/6, 2009 at 6:16 Comment(2)
You have to love MS documentation. "A Nullable<(Of <(T>)>) value of type Boolean that signifies how a window was closed by the user." Gee, that helps.Goaltender
Sounds like the kind of documentation where the writers weren't allowed to talk to the developers and ask questions, but were only allowed access to what they had on the screen...Maryannamaryanne
S
31

The method always returns true or false, and this is always equal to the DialogResult property of the window at the time it closes.

But the DialogResult property is null before the window is closed, and another thread could check the property. So it kind of makes sense that the return value is a nullable boolean to match the property, even though it is never actually null.

Simar answered 13/6, 2009 at 6:32 Comment(4)
Not sure where you get the idea that another thread could check DialogResult. If you try, you get an InvalidOperationException ("The calling thread cannot access this object because a different thread owns it.")Plexiform
Not another thread, but any code running (say) on an event handler on the dialog could retrieve the value of DialogResult before it completes. Personally I think it's a poor design choice. It should have been non-nullable, the getter throwing an exception if accessed before the dialog quits.Resistless
I just had this method return null and went to this question to look it up, so (since at least now) this method definitely can return null. There was no exception whatsoever, the window simply didn't show up for whatever reason and this method simply returned - null. I am now left with nothing else than to debug WPF code to find out why.Beverlee
Setting the DialogResult to either false or true will close the window. Setting a property to its current value usually does not have side effects (comment from the source code of Window: "// According to the new design, setting DialogResult to its current value will not have any effect."), so it's much cleaner to let DialogResult have a a different initial value than either of these - thus it must be nullable. Of course, the ShowDialog() method did not have to return the value of DialogResult directly, but that's what it does - or, rather, its backing field _dialogResult.Letha
P
3

If I return DialogResult = null in the Click event for a button, the window remains open.

private void OkButton_Click(object sender, RoutedEventArgs e)
{
   Button btn = sender as Button;
   if ( btn != null )
   {
       // forces all control to update...
       btn.Focus();
   }

   // TEST IF OK TO CLOSE
   bool rc = _vm.ProcessOkCommand();
   if (rc)
   {
      DialogResult = true;
   }
   else
   {
      DialogResult = null;
   }
}


<Button Content="OK" Name ="cmdOK" IsDefault="True" Click="OkButton_Click"/>
Pythian answered 18/3, 2010 at 4:40 Comment(2)
Right, that's my point -- it looks like ShowDialog won't ever return null.Plexiform
It is no better than doing nothing than setting DialogResult = null;. Effectively both are same I guess. Correct me if I'm wrong.Mcclellan
C
3

I can give you an example I just encountered. Window.ShowDialog() will return null when you perform the following steps:

  • You first close all of your Application's windows.
  • All other Window objects that have been instantiated up until now with the new keyword are closed.
  • You try to instantiate a new Window and try calling Window.ShowDialog() on it. It will return null.

This is because, presumably, you have no existing Window under which your new dialog can bind to in order to behave like a dialog which owns the topmost window state.

Consequently answered 9/4, 2019 at 17:49 Comment(0)
L
2

A call to window.ShowDialog() can return null in very special circumstances, which I ran into by chance:

If the window.Closing event is caught in the following manner

        var window = new DialogTestWindow();
        window.Closing += (o, e) => { e.Cancel = true; window.Hide(); };
        MessageBox.Show(window.ShowDialog().ToString());

then setting DialogResult = true or DialogResult = false from the dialog window will cause the window.ShowDialog() call to return null. Calling Hide() from the dialog window will cause it to return false.

Edit: The comments in the source code to Window clearly say that the intention is that a call to ShowDialog() should never return null. However, when Hide() is called from within the Closing event, the various checks that should prevent this fail: Hide() sets _dialogResult to false, but a check for whether the closing of the window has been cancelled subsequently sets it to null.

Letha answered 11/1, 2022 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.