0

I'm pretty new to C# development and I'm trying to run some code before the user quits the application completely. I tried to look online but did not get anything. Here is my code and it's not working. Thanks:

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

            Console.WriteLine("Hello World!");

        }

        void DataWindow_Closing(object sender, CancelEventArgs e)
        {
            Console.WriteLine("Goodbey World!");
        }
    }
}
Gaurang Dave
  • 3,956
  • 2
  • 15
  • 34
JoshJoshJosh
  • 897
  • 2
  • 11
  • 20
  • 1
    you mean your "Goodbey World!" is not being written ? BTW if its windows app, you should put that in `MessageBox` . I hope this `DataWindow_Closing` event is subscribed with `MainWindow`'s closing event. – Amit May 11 '18 at 03:49
  • Isn't this a paradox? Who will win, the strongest man or the heaviest rock? The same in Computer Science, who will win, the DoBeforeQuit() or QuitBeforeContinue() – theBotelho May 11 '18 at 03:50
  • 1
    What do you expect to happen? If that's sent to the console, nothing prevents the console from exiting at the end, so that goodbey (sic) message will display for a millisecond only. – Andrew May 11 '18 at 03:52
  • 1
    Possible duplicate of [Execute code when a WPF closes](https://stackoverflow.com/questions/10018308/execute-code-when-a-wpf-closes) – Gaurang Dave May 11 '18 at 03:54
  • @andrew has a point. have you tried putting a breakpoint on "goodbey" ? – Slack Groverglow May 11 '18 at 04:06

3 Answers3

3

Here is a way to control both opening and closing actions in WPF.

Under App.xaml, open App.xaml.cs and change as follows.

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private void App_Startup(object sender, StartupEventArgs e)
        {
            // Code for before window opens (optional);

            var mainWindow = new MainWindow();
            mainWindow.Show();

            mainWindow.Closed += Window_Closed;
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            // Code for after window closes goes here.
            MessageBox.Show("Goodbye World!");
        }
    }
}

And change App.xaml as follows to use:

<Application x:Class="WpfApp1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp1"
             Startup="App_Startup" >
    <Application.Resources>

    </Application.Resources>
</Application>

The key change here is Startup="App_Startup".

These make it easier to understand exactly when each action is occurring, as it makes the entry and exit points clearer.

Note: This will not work if you want the user to be able to cancel quitting the app, but from your example code that is not what you are looking for.

JJJulien
  • 269
  • 2
  • 13
  • Glad it worked for you. BTW, I now notice that you did not have "Closed += DataWindow_Closing;" in the constructor code you posted. This is what connects the method with the event. Adding that and changing "Console" to "MessageBox" also works. – JJJulien May 11 '18 at 05:21
2

Reading from the post you want to display a message to the user when they are closing the application. Since you are new to C# I would suggest staying with Console Applications before moving on to WPF which is a very well developed and documented framework in which it allows you to design your application using what is called XAML Extensible Application Markup Language

Sidenote Console.WriteLine("Hello World"); will print out to the output window by default and should not show any other visual references.

Never the less. You want to call the event Closing and inside that you would want to call upon the MessageBox class and use one of it functions which takes a literal string as a parameter. MessageBox.Show("Goodbye user!");

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    //When your application finished initializing it's components this will run
    MessageBox.Show("Hello User!");
        }

//This being the event
        private void mainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            MessageBox.Show("Goodbye User!");
        }
    }

Aswell as the XAML, because you are routing the event from the XAML (Frontend)to backend

<Window x:Name="mainWindow" x:Class="HelloWorld.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HelloWorld"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" Closing="mainWindow_Closing">
    <Grid>

    </Grid>
</Window>
Jess Chan
  • 391
  • 2
  • 14
  • Thanks man! I tried it but the mainWindow_Closing function is never called for some reason – JoshJoshJosh May 11 '18 at 05:13
  • @JoshJoshJosh I updated the answer providing the corresponding XAML code. – Jess Chan May 11 '18 at 05:21
  • @JoshJoshJosh Remember that WPF is built upon a framework that is used for MVVM which makes Databinding take a huge part in it. So defining the event back-end would be bad practice, try seperating the business logic from the UI as much as possible. – Jess Chan May 11 '18 at 05:23
1

Your console window is showing for a split second and then closing straight away. You need to read a key from the user and wait for input to keep it open.

void DataWindow_Closing(object sender, CancelEventArgs e)
    {
        Console.WriteLine("Goodbey World!");
        Console.ReadLine();
    }

This is assuming your function is getting hit at all.

L.B
  • 88
  • 3