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 m
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.
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.
The DialogResult
property is defined on the Window
class. Not all Window
s 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
.
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.
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.