How can I show confirmation dialog in WPF, when window is closing?

ccbuilder
ccbuilder used Ask the Experts™
on
I need to do a task in WPF, which was no problem in WinForms - when user attempts to close main window and there are unsaved data, show confirmation dialog and potentially cancel the closing.
I tried to use Window.Closing event for this. Event comes, cancellation works, but problem is, that I can not show a modal dialog. Attempt to do it results in InvalidOperationException with message like "Can not set Visibility to Visible, or call Show, ShowDialog, or Close  while a window is closing." This is even described in documentation. So, how can I display simple modal dialog like "There are unsaved data, do you want to save them? Yes, No, Cancel"?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
Check the attached code. I am showing Window2 when Window1 is closed.
///////////////////////////////////////////////
// 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" Closing="Window_Closing" WindowStartupLocation="CenterScreen">
    <Grid>
        
    </Grid>
</Window>

///////////////////////////////////////////////
// Window1.xaml.cs
///////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Window2 win2 = new Window2();
            win2.ShowDialog();

            if (win2.Result == false)
            {
                e.Cancel = true;
            }
        }
    }
}

///////////////////////////////////////////////
// Window2.xaml
///////////////////////////////////////////////
<Window x:Class="WpfApplication1.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window2" Height="120" Width="250" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50*"></RowDefinition>
            <RowDefinition Height="50*"></RowDefinition>
        </Grid.RowDefinitions>
        <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="Do you want to close?"></Label>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button Name="YesBtn" Width="100" Height="30" Margin="5" Content="Yes" Click="YesBtn_Click"></Button>
            <Button Name="NoBtn" Grid.Column="1" Width="100" Height="30" Margin="5" Content="No" Click="NoBtn_Click"></Button>
        </Grid>
    </Grid>
</Window>

///////////////////////////////////////////////
// Window2.xaml.cs
///////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window2.xaml
    /// </summary>
    public partial class Window2 : Window
    {
        public bool Result { get; private set; }

        public Window2()
        {
            InitializeComponent();
            Result = false;
        }

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

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

Open in new window

Author

Commented:
Well, thanks a lot. Although I'm feeling stupid. The fact that such simple example works forced me to go deeper into our company libraries.
There I realized that base class for my main window already handles Closing event and under some circumstances calls Application.Shutdown.
So, it was not window closing, but application closing what prevented me from showing the dialog.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial