0

I'm stumbling my way through my first WPF desktop application using C# and am trying to stick to good programming practice by not repeating code. I've come a little unstuck when trying to add an event handler to buttons in different windows.

I have two windows (named 'MainWindow' and 'ViewContent') which both contain buttons to exit the application.

The buttons are both identical in XAML, and are created in separate windows:

<Button Click="Exit_Application" />

The event handler for a button click will then run:

public void Exit_Application(object sender, RoutedEventArgs e)
{
    // Exit the application
    System.Windows.Application.Current.Shutdown();
}

This works when I include the 'Exit_Applicaiton' method in the code-behind for both windows, but I was hoping to only have to include this method once and be able to use it globally. I've searched around and can't seem to find any information on using click event handlers globally, Is this possible?

Any help would be greatly appreciated.

  • You need to start with a well known design pattern like MVVM and look for WHY rather than WHAT, while learning it. This will help you understand whether it is worth repeating or not repeating a certain piece of code and also how to reuse it. That should be the starting point. – bit Oct 11 '19 at 07:01
  • @bit Thanks for the advice, I'm aware of MVVM before but never properly looked into it (there are a lot of conflicting resources). I'll take a look into this now. – TatTheFlame Oct 11 '19 at 07:08

3 Answers3

1

There are a few ways to handle this scenario (listed below), however I would recommend looking into the MVVM pattern to help clarify how to structure your application.

1. Shared method within App

Create a public method (example below) within the App class (typically App.xaml.cs in the project root). The App class is accessible from anywhere within your application so could be used to share exit logic that can be triggered from multiple <Window\>.

public void Shutdown()
{
    // Insert any code that needs to run before shutdown

    System.Windows.Application.Current.Shutdown();
}

From within each <Window\> you could call App.Shutdown() to exit the application.

2. Decide code sharing is not needed for this case

If the only line of code that needs to run when a user exits your application is System.Windows.Application.Current.Shutdown(); then there is no need to "share" this code. There is no logic within this code therefore calling this method from both <Window\> could be just fine.

Jesse Johnson
  • 1,638
  • 15
  • 25
0

The fact that you're using click events on buttons and asking the question means you don't understand commands in wpf. Commands in particular, binding and resources are the big plusses of using WPF. If you're not using these then that's ok for a trivial application but commercial teams use MVVM and even a hobby app of any substance will benefit from adopting this.

There is, however, a learning curve and if you're only ever writing one app then learning MVVM might not be worthwhile.

Either way, you can use a command by binding the command property of your buttons to a class implements icommand.

Usually, a command will be doing something or other with data and you'd be working with a viewmodel so a simple command would be in a property of a viewmodel like:

https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx

In this case your command doesn't need any data and is just working with the app. Which you can do from any piece of code.

You can therefore use a static class implements icommand. That could be just directly in the class or by using a library already does this for you - like MVVM light.

From this thread:

WPF Commands, How to declare Application level commands?

Here's a simple implementation:

class MyCommand : ICommand
{
    // Singleton for the simple cases, may be replaced with your own factory     
    public static ICommand Instance { get; } = new MyCommand();

    public bool CanExecute(object parameter)
    {
          return true; 
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
         System.Windows.Application.Current.Shutdown();    
    }   

}

Andy
  • 11,864
  • 2
  • 17
  • 20
0

you can declare in MainWindow (or another class) static ICommand ExitAppCommand and use it

class:

public static ICommand ExitAppCommand { get; } = new ActionCommand(() => System.Windows.Application.Current.Shutdown());

XAML:

<Button Command="{x:Static youClassNamespace:youClass.ExitAppCommand}">
Artem
  • 9
  • 3