19

Can anyone think of a good explanation for the fact that result of a dialog is a nullable bool in WPF? This has always baffled me. In WinForms it was an enum type and that made a lot more sense to me.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
PeterAllenWebb
  • 10,319
  • 3
  • 37
  • 44

5 Answers5

15

The DialogResult property is defined on the Window class. Not all Windows are dialogs. Therefore, the property isn't relevant to all windows. A Window that has been shown via Show() rather than ShowDialog() will (presumably, unless you set it for some reason) have DialogResult = null.

Here's a simple example to demonstrate:

Window1.xaml:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Button Name="b1">Show</Button>
        <Button Name="b2">ShowDialog</Button>
    </StackPanel>
</Window>

Window1.xaml.cs:

using System.Windows;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            b1.Click += new RoutedEventHandler(b1_Click);
            b2.Click += new RoutedEventHandler(b2_Click);
        }

        void b1_Click(object sender, RoutedEventArgs e)
        {
            var w = new Window();
            w.Closed += delegate
            {
                MessageBox.Show("" + w.DialogResult);
            };

            w.Show();
        }

        void b2_Click(object sender, RoutedEventArgs e)
        {
            var w = new Window();
            w.ShowDialog();
            MessageBox.Show("" + w.DialogResult);
        }
    }
}

When you close the windows, you'll notice that the dialog has a DialogResult of false, whilst the non-dialog has a null DialogResult.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • While this is true and probably pertinent there was already a 'None' value in the DialogResult enum which would have fulfilled the purpose of null in this example quite comfortably. So I doubt a desire to have a null value was reason enough to move from the established model. – Martin Harris Jun 12 '09 at 15:45
  • 1
    To me, null means completely irrelevant whereas None suggests it's relevant but not yet set. *shrugs* Semantics. – Kent Boogaart Jun 12 '09 at 15:48
  • Funnily enough I would read it the other way. Null is an unset value and None means that there isn't and won't ever be a DialogResult. Maybe that type of confusion was reason enough to change the model. – Martin Harris Jun 12 '09 at 15:53
  • 1
    "The DialogResult property is defined on the Window class. Not all Windows are dialogs." These two sentences seem true, and hilarious at the same time. – PeterAllenWebb Apr 30 '10 at 14:39
6

In my opinion this was done because in most cases you don't need the generalized specialized options like Retry or Ignore.

If you need more than OK/Cancel, you are supposed to use some kind of task dialog, e.g. with written-out answers. That way, you're not limited to the few enum values someone thought of some decades ago, and the DialogResult is just positive/negative for basic use and you can implement your own property that is specific to your advanced needs. Therefore only true/false is needed, and null indicating that the window has not been closed yet (no value has been assigned to the property yet).

If you have a dialog that is more than just a question the user should answer (e.g. an entry form), you're typically better off with OK/Cancel, so you don't need more values.

OregonGhost
  • 23,359
  • 7
  • 71
  • 108
  • Then why Nullable(Of Boolean), why not just Boolean, or ThreeState? – Shimmy Weitzhandler Nov 18 '09 at 21:50
  • bool? is, in my opinion, easier to handle than yaetr (yet another enum to remember). And the null value may be useful for bindings as an unassigned value, in contrast to definite true/false values. Of course, *I don't know* why it's like that, just guessing :) – OregonGhost Nov 19 '09 at 09:46
2

According to the MSDN documentation:

DialogResult is null when the dialog box is shown but neither accepted nor canceled.

But I'm not sure how that could happen unless you're dealing with multiple threads accessing the dialog.

The documentation says is false when one of the following things happen:

  • PressesALT+F4.
  • Clicks the Close button.
  • Selects Close from the System menu.
Max Schmeling
  • 12,363
  • 14
  • 66
  • 109
  • I think it happens when the user clicks the Close button on the top-right of the window. – Samuel Jack Jun 12 '09 at 15:40
  • not according to the documentation i linked to... i'll edit with more detail – Max Schmeling Jun 12 '09 at 15:46
  • @Max, if you call `Show` then the call returns to you (ie. it's a non-blocking call), so you're free to interrogate the `DialogResult` value straight away. It's only if you call `ShowDialog` that the call blocks until the dialog is dismissed. However in the latter case, you're still free to interrogate the object from another thread, as you point out. – Drew Noakes Nov 06 '09 at 16:44
0

ShowDialog will always return true or false. DialogResult will only take the null state when the dialog is open. Transitioning from null to true or false will close the dialog and make the original call to ShowDialog return.

pjbelf
  • 641
  • 4
  • 4
0

IMO this is because DialogResult isn't always used. You see, you can only set DialogResult if the window is called by its ShowDialog() method, if you call it with its Show() method, and try to set DialogResult to anything, it'll throw an InvalidOperationException. So I think that is the reason it's nullable, in case you call the window with the Show() method, it'll be null, if you call it using ShowDialog(), it's up to you.

Carlo
  • 25,602
  • 32
  • 128
  • 176