30

I show a WPF window using ShowDialog() from the calling window. The window opens and is modal as expected. However, in my OK and Cancel button's click events in the dialog window I set this.DialogResult = true (or false) respectively, and the value does not get set. The window closes as expected, but DialogResult is still null.

Is this a bug in WPF? Or is there a reason the DialogResult property cannot be set yet does not throw an exception? The window is not hosted in a browser.

Code in the calling window:

Window2 win = new Window2();
bool? result = win.ShowDialog();
if (result.HasValue && result.Value) {
   //never gets here because result is always null
}

Code in the dialog window:

this.DialogResult = true;
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
quinnapi
  • 346
  • 1
  • 3
  • 7
  • How are you setting DialogResult to a bool? It should be an enum, like DialogResult.OK – Brandon May 22 '09 at 16:24
  • 13
    No, in WPF, if you open a Window object with it's ShowDialog() method, you can set DialogResult to a boolean. – Carlo May 22 '09 at 16:26
  • Can you post the contents of your `` definition here? Maybe it's something particular to the way you're initialising the window. – Drew Noakes Nov 06 '09 at 16:36
  • 1
    What is that Window2? Did you derive your own Window-class from Window? Then it's probably something wrong in your Window2-class, you should post sourcecode of it. – Simon D. Dec 14 '10 at 14:19
  • I just ran into this problem and it seems to be a bug when deriving from your own Window class. Not sure how to fix it. – craftworkgames Jul 02 '13 at 03:33

10 Answers10

18

DialogResult is a nullable bool. However you do not have to cast it to get it's value.

bool? result = myWindow.ShowDialog();
if (result ?? false)
{
  // snip
}

The ?? sets the default value to return if the result is null. More information: Using Nullable Types (C# Programming Guide)

As for the original question, the only time I have seen and traced this issue is when the window was being disposed between setting the DialogResult and closing the window. Unfortunately the only advice that I can offer is for you step through your code and check the order of the operations. I believe that I "fixed" it by setting the DialogResult and then explicitly closing the window.

CJBS
  • 15,147
  • 6
  • 86
  • 135
Dennis
  • 20,275
  • 4
  • 64
  • 80
10

Well first of all you have to take into account that it returns a nullable bool (bool?), so in order to compare it or set it to another variable you have to cast it to a regular bool

bool result = (bool)myWindow.DialogResult;

As for it being null... I don't see why that should happen, unless it's somehow being set back to null AFTER being set to true or false. Can you show your code?

EDIT:

Your code worked fine for me, this is what I have in the second window:

private void button2_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = false;
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}

And in Window1:

private void window1_Loaded(object sender, RoutedEventArgs e)
{
    Window2 win = new Window2();

    bool? result = win.ShowDialog();

    if (result.HasValue && result.Value)
    {
        //it DID get here
    }
}

Is there any big difference?

Carlo
  • 25,602
  • 32
  • 128
  • 176
  • 3
    In a debugging session, I check the value of DialogResult immediately after setting it to true and it is still null. – quinnapi May 22 '09 at 16:33
  • No difference. In fact, I do the exact same thing with several other windows in the same project, and they all work fine. – quinnapi May 22 '09 at 16:59
  • Try using bool? result = win.DialogResult; AFTER win.ShowDialog()... I know it's not promising but let's try. Is there any more info you think I might need to recreate the scenario? This is some odd behavior... – Carlo May 22 '09 at 17:09
  • 5
    @quinnapi haha 2 years later, and I'm getting the same problem. I just realized I was reading my own answer. Annoying! – Carlo Jul 01 '11 at 20:46
  • @Carlo - have a look at http://stackoverflow.com/a/1759505/319980 for a very elegant way of replacing those code-behind event handlers with a simple attached property. – David Keaveny May 25 '12 at 03:55
8

I have just had exactly the same problem and it seems to be caused by my overriding the OnClosing() method. I needed to override OnClosing() to stop the user closing the modal window via the close (X) button.

When I comment out the OnClosing() method, the problem goes away and the DialogResult is returned with the expected values of true or false, as set.

For interest here was my button click handlers and OnClosing method:

private void AlternateButton_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = false;
    buttonHasBeenClicked = true;
    this.Close();
}

private void DefaultButton_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
    buttonHasBeenClicked = true;
    this.Close();
}

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);
    if (!buttonHasBeenClicked)
    {
        // Prevent the user closing the window without pressing one of the buttons.
        e.Cancel = true;
    }
}
dodgy_coder
  • 12,407
  • 10
  • 54
  • 67
  • As a follow up to this, I have just removed the close (x) button from the window so that I no longer need to override OnClosing(). More here: http://stackoverflow.com/questions/743906/how-to-hide-close-button-in-wpf-window – dodgy_coder Nov 08 '11 at 07:42
  • Even if the close (x) button is hidden, the user could still close the window by hitting Alt-F4 or clicking a button whose "IsCancel" property is set "True". – Ed Noepel Apr 03 '13 at 15:02
  • I had similar issue. Your post helped! Thank you! – al2suarez Dec 01 '17 at 00:56
  • I had the same trouble and thanks to @dodgy_coder I found the root of the problem. The `DialogResult` setter calls `Close` [link](https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Window.cs,82d83d68eca4bf03). Your OnClosing event handler sets `e.Cancel` which apparently resets `DialogResult`. The solution is to first set `buttonHasBeenClicked` (to prevent cancelling closing), then set `DialogResult`. – Jiří Skála Jul 22 '19 at 11:34
4

I have been into this problem too, and the only way i have found to fix it was using this code in my Class :

public new bool? DialogResult { get; set; }

and after setting my DialogResult it work out for me !! ( very strange issue ). this was the code i was using :

cmdCancel = new RelayCommand(() => { DataContact.Reload(); this.DialogResult = false; this.Close(); });

and to open my dialog :

public static MessageBoxResult ShowQuestionYesNo(string message)
        {
            POLMessageBox w = new POLMessageBox("سوال", MessageBoxType.QuestionYesNo, message);
            w.ShowDialog();
            var b = w.DialogResult;
            if (b == true) return MessageBoxResult.Yes;
            if (b == false) return MessageBoxResult.No;
            return MessageBoxResult.No;
        }
Ehsan Zargar Ershadi
  • 24,115
  • 17
  • 65
  • 95
  • After reviewing several of these answers, this is what I ended up doing too. It's ugly and requires documentation and comments, but it's the only way to avoid getting my toes stepped on by WPF. – Grault Mar 11 '16 at 20:58
2

Do you close the window before u set the DialogResult? You should post the whole content of your button event-handlers.

batzen
  • 161
  • 2
  • 4
0

I just ran into the problem too. It turns out I had set DialogResult inside a brace of an IF statement and for this reason (as odd as it may seem) caused the error. As soon as this single line was removed, the problem was resolved.

private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        if (!string.IsNullOrEmpty(startBlockPosBox.Text))
        {
          .. do stuff ..
        }
        else
        {
          .. do stuff ..
          DialogResult = true; // this line caused the problem
        }

        DialogResult = true;
    }
dracore
  • 59
  • 4
0

I have the following in the dialog window page. (dialogwindow.xaml.cs)

   private void dlgWindowYesButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
        this.Close();
    }

    private void dlgWindowNoButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;
        this.Close();
    }

In the calling page I used the dialogwindow like this:

dialogwindow dWinObj = new dialogwindow();
if(dWinObj.ShowDialog().Value == true)
{
  //perform the operation when the user clicks "Yes"
}
Kishore
  • 653
  • 6
  • 16
0

The problem is due to the life of the form:

Dialog event private void _loginViewModel_LoginEvent(object sender, LoginViewModel.LoginEventArgs e) { DialogResult = true; this.Close(); }

Works:

var login = new Login();
var result = login.ShowDialog();

Does NOT work:

var result = new Login().ShowDialog();
jlo-gmail
  • 4,453
  • 3
  • 37
  • 64
0

I fixed this problem with adding this.close() after that add this.DialogResult=true and window.ShowDialog() return true.

private void Button1_Click(object sender, RoutedEventArgs e)
{
    this.Close();
    this.DialogResult = true;
}
-1

I had a similar issue, but my issue came from the code within my closing statement. I was trying to Dispose() a List before the window closed, and then set the List<> property to null... it was choking on the set property when I was trying to set its value to null so I came up with the following clumsy workaround in my set property method and everything worked afterward:

    List<SettingItem> settingItems;
    public IEnumerable<SettingItem> Settings
    {
        get
        {
            return settingItems.OrderBy(t => t.Name).AsEnumerable();
        }
        set
        {
            if (value == null)
            {
                settingItems.Clear();
            }
            else
            {
                settingItems = value.ToList();
            }
        }
    }