Execution of code after user clicks on close icon [duplicate] - c#

I am not familiar with using event handlers, and I was wondering if anyone had or could direct me to some code that shows how to use an event handler that will execute code on the Close/Closed event?
I know this can be done because of this answered question:
Run code on WPF form close
But I need some direction.
Thank you =)

It's just this XAML
<Window ... Closing="Window_Closing" Closed="Window_Closed">
...
</Window>
and code for both the Closing and Closed events
private void Window_Closing(object sender, CancelEventArgs e)
{
...
}
private void Window_Closed(object sender, EventArgs e)
{
....
}

If you want to do it all from code behind put this in your windows .cs file
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Closed += new EventHandler(MainWindow_Closed);
}
void MainWindow_Closed(object sender, EventArgs e)
{
//Put your close code here
}
}
}
If you want to do part in xaml and part in code behind do this in xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Closed="MainWindow_Closed">
<Grid>
</Grid>
</Window>
and this in .cs
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
void MainWindow_Closed(object sender, EventArgs e)
{
//Put your close code here
}
}
}
The above to examples you can apply to any form in a xaml app. You can have multiple forms. If you want to apply code for the entire application exit process modify your app.xaml.cs file to this
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnExit(ExitEventArgs e)
{
try
{
//Put your special code here
}
finally
{
base.OnExit(e);
}
}
}
}

You can override the OnExit function in App.Xaml.cs like this:
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnExit(ExitEventArgs e)
{
//do your things
base.OnExit(e);
}
}

If you are using C# on Microsoft Visual Studio, the following worked for me.
In your Window.cs file
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Name_Space
{
public partial class Window : Form
{
public Window()
{
InitializeComponent();
//...
}
private void Window_Load(object sender, EventArgs e)
{
//...
}
private void Window_Closed(object sender, EventArgs e)
{
// Your code goes here...!
}
}
}
In your Window.Designer.cs file add this line to the following method
...
private void InitializeComponent()
{
...
//
// Window
//
...
this.Closed += new System.EventHandler(this.Window_Closed); // <-- add this line
}
...

Related

WPF Programming, How to move an event to another class (outside)

I have the problem that I want to add an event from XAML directly to another class.
The standard class, which is used, is the MainWindow.
In my situation I want to define, which class should be used for the event.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Closing_Event(object sender, System.ComponentModel.CancelEventArgs e)
{
}
}
public class differentClass
{
public differentClass()
{
}
private void Window_Closing_Event(object sender, System.ComponentModel.CancelEventArgs e)
{
}
}
Maybe someone can help me, how I can use the event from the second class without any code in the MainWindow.
There is a Behavior class for this purpose. You will need to add the reference to the System.Windows.Interactivity in the project: How to add System.Windows.Interactivity to project?
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
public class CustomWindowHandlerBehavior: Behavior<Window>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Closing+= Window_Closing_Event;
}
protected override void OnDetaching()
{
AssociatedObject.Closing-= Window_Closing_Event;
base.OnDetaching();
}
private void Window_Closing_Event(object sender, System.ComponentModel.CancelEventArgs e)
{
//...
}
}
using this behavior in XAML:
<Window
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Behaviors>
<local:CustomWindowHandlerBehaviour />
</i:Interaction.Behaviors>
<Window/>

Cannot access class from another class c#

I'm trying to access public partial class ChooseExercises : Window from public partial class YourProgress : Window, but it throws an exception:
System.InvalidCastException: 'Unable to cast object of type 'GymCheckList.YourProgress' to type 'GymCheckList.ChooseExercises'.'
The way I'm trying to access it is:
namespace GymCheckList
{
/// <summary>
/// Interaction logic for YourProgress.xaml
/// </summary>
public partial class YourProgress : Window
{
public YourProgress()
{
InitializeComponent();
}
private void TabThursday_Loaded(object sender, RoutedEventArgs e)
{
ChooseExercises ce = (ChooseExercises)Application.Current.MainWindow;
var lol = ce;
}
If I use ChooseExerises ce = new ChooseExercises(); it gives me empty ce incstance. What may cause the exception?
Thanks!
Edit
In ChooseExeprises class I used similar code to access the MainWindow class and it works fine:
namespace GymCheckList
{
/// <summary>
/// Interaction logic for ChooseExercises.xaml
/// </summary>
public partial class ChooseExercises : Window
{
public ChooseExercises()
{
InitializeComponent();
}
private List<string> data = new List<string>();
public void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
MainWindow kek = (MainWindow)Application.Current.MainWindow;
Obviously your main window is a YourProgress but you could try to get a reference to the ChooseExercises window using the Application.Current.Windows collection:
private void TabThursday_Loaded(object sender, RoutedEventArgs e)
{
ChooseExercises ce = Application.Current.Windows.OfType<ChooseExercises>().FirstOrDefault();
...
}

Event recognition C# WPF

I got an Problem with Events. I got a first Window which looks like this:
using System.Windows;
namespace EventsTests
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
/*Binding Event to MainWindow
dont work until you will help*/
MainWindow mw = new MainWindow();
mw.RaiseEvent += raiseEvent_EventHandler;
}
public void raiseEvent_EventHandler()
{
MessageBox.Show("MAINWINDOW Event Fired");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SecondPage sp = new SecondPage();
sp.Show();
}
}
}
Now the seconde Page donĀ“t do very much:
using System.Windows;
namespace EventsTests
{
/// <summary>
/// Interaction logic for SecondPage.xaml
/// </summary>
public partial class SecondPage : Window
{
SecondPageViewModel spvm = new SecondPageViewModel();
public SecondPage()
{
this.DataContext = spvm;
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
spvm.raiseEventActivate();
}
}
}
And at last I have the SecondPageViewModel:
namespace EventsTests
{
public delegate void raiseEventEventHandler();
class SecondPageViewModel
{
public event raiseEventEventHandler raiseEvent;
public void raiseEventActivate()
{
if(raiseEvent != null)
{
raiseEvent();
}
}
}
}
Now I want, when I click the button on the second page, the Event is fired an the MainWindow recognise the event.
With this code i get the Error:
Error 1 Cannot assign to 'RaiseEvent' because it is a 'method group'
Can someone help me? Or give me an example?
Thanks for every hint ;)
RaiseEvent is not your event, it's a method of the Window.
I think you want to do this:
SecondPage sp = new SecondPage();
sp.raiseEvent += raiseEvent_EventHandler;
sp.Show();
That is, register an event handler with the second page event.
Though I wouldn't advocate event handlers for this. While I don't know what you are trying to achieve I'd rather do something like pass a ViewModel object to the SecondPage and the main window can respond to state changes on that ViewModel.
In WPF, I always aim for zero code behind.
In response to discussion, how one VM could have reference to another. First pass the VM in:
SecondPageViewModel spvm;
public SecondPage(SecondPageViewModel model)
{
spvm = model;
this.DataContext = spvm;
InitializeComponent();
}
Then the SecondpageVM takes a MainVM as a paramter in the constuctor:
SecondPage sp = new SecondPage(new SecondPageViewModel(mainVM));
Updates to the main model are done within the SecondPageViewModel. The second page itself has no references to it.
ThirdPage tp = new ThirdPage(new ThirdPageViewModel(spvm))
Third page VM can access main page VM via property on second page vm: spvm.MainVm
In MainWindow you're trying to subscribe to a Window method, instead of your raiseEvent. And certainly you don't need to instantiate another MainWindow...
Your MainWindow code should be something like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void raiseEventFromSecondPage_EventHandler()
{
MessageBox.Show("MAINWINDOW Event Fired");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SecondPage sp = new SecondPage();
sp.raiseEventFromSecondPage += raiseEventFromSecondPage_EventHandler();
sp.Show();
}
}
You then need that SecondPage exposes the raiseEvent. This will be a different event from the one in its ViewModel, but you'll chain both.
public partial class SecondPage : Window
{
SecondPageViewModel spvm = new SecondPageViewModel();
public event raiseEventEventHandler raiseEventFromSecondPage;
public SecondPage()
{
this.DataContext = spvm;
spvm.raiseEvent += raiseEvent_EventHandler;
InitializeComponent();
}
public void raiseEvent_EventHandler()
{
if (raiseEventFromSecondPage != null)
raiseEventFromSecondPage();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
spvm.raiseEventActivate();
}
}

How to run MainWindow_Loaded from App.xaml.cs?

I have a WPF app, in file Main.xaml.cs I have the following constructor:
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
from another class:
In App.xaml.cs
I need to fire an event which will make run method MainWindow_Loaded in Main.xaml.cs
Any idea how to do it?
You can do this by manually creating the MainWindow in your App class. To do it, remove the StartUp attribute from the App.xaml so that it looks like this...
<Application x:Class="Anything.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
</Application>
In your App.xaml.cs class, override the OnStartup method like this...
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow mw = new MainWindow();
mw.Loaded += mw_Loaded;
mw.Show();
}
void mw_Loaded(object sender, RoutedEventArgs e)
{ // loaded event comes here
throw new NotImplementedException();
}
}
This override manually creates the MainWindow and shows it. It also subscribes to the Loaded event and receives the notification in the mw_Loaded method. You can also call the window's method directly because you have the window instance.
Alternatively, you can overload the MainWindow constructor and pass it an Action delegate. It would look like this...
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow mw = new MainWindow(DoSomething);
mw.Show();
}
public void DoSomething()
{
}
}
And the MainWindow would look like this...
public partial class MainWindow
{
private readonly Action _onLoaded;
public MainWindow(Action onLoaded)
{
_onLoaded = onLoaded;
InitializeComponent();
Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
_onLoaded();
}
}
That gives you two alternatives, there are other ways also, but these are the most expedient. As Sheridan pointed out, tinkering with a window's loaded event can have confounding side effects, like re-entrancy. The WPF forefathers envisioned it as a lifetime event.

C# WPF page switching

I want to accomplish something like they have in Modern UI for WPF. I have MainWindow : NavigationWindow, which source is page /main.xaml and my code in it looks like this:
public partial class main : Page
{
public main()
{
InitializeComponent();
}
private void settings_Click(object sender, RoutedEventArgs e)
{
settings settingsmenu = new settings();
this.NavigationService.Navigate(settingsmenu);
}
}
The problem is, that when i switch pages, annoying sound appears. I think it's named "navigation start". Can i prevent it from playing ? Or is there another way to switch pages, that doesn't play it ? Thanks in advance.
(sorry if this question is dumb, but I'm new to WPF)
Here is a small workaround. Original sources I found here:
http://social.msdn.microsoft.com/Forums/vstudio/en-us/843677f4-8f0b-46cb-986c-92e8042d0707/stupid-problem-with-webbrowser-control
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
private RegistryKey regKeyCurrentUser;
private RegistryKey regSubKeyCurrent;
public Page1()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var page2 = new Page2();
this.NavigationService.Navigate(page2);
}
private void Page1_OnLoaded(object sender, RoutedEventArgs e)
{
regKeyCurrentUser = Registry.CurrentUser;
regSubKeyCurrent = regKeyCurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
regSubKeyCurrent.SetValue("", "");
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
var regSubKeyDefault = regKeyCurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Default");
regSubKeyCurrent.SetValue("", regSubKeyDefault.GetValue("",""));
}
}
}

Categories

Resources