WPF call Window_Closing event from code behind - c#

Recently I have been experimenting with WPF. I was building a little program, but then I stumbled across a little problem. I tried to call the Window_Closing method from the code behind, it told me that I needed to give it cerntain parameters, but I don't have those parameters in the method I am trying to call it from.
This is my code:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// My Window Closing code
}
private void Application_Exit(object sender, RoutedEventArgs e)
{
// Here is where I am trying to call it, giving a empty parameter with it.
// But it doesn't seem to work.
Window_Closing(null, EventArgs.Empty)
}
What I want
If a cenrtain button is called, I want the Window_Closing event to be called.
Anyone who knows the solution?

In your Designer, click on the Button and open its property window. There you select the "Events" - the "lightning" and choose the Click event to execute your Window_Closing method. There is a drop down in which you should be able to select it. If not, enter your method name there and press "Enter" to let VS generate the code-behind method.

Add "Window_Closing" & "Close_Click" in the XAML file (MainWindow.xaml) as follows.
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Closing="Window_Closing">
<Grid>
<Button x:Name="Close" Content="Close" Click="Close_Click" Width="100" Height="30"/>
</Grid>
Then in the code behind file (MainWindow.xaml.cs) add the following code. Here the window close command is called from the button click event handler which in turn closes the window, and then the 'Window_Closing' event handler will be automatically called.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
}
private void Close_Click(object sender, RoutedEventArgs e)
{
Close();
}
}

Just close the window. Then the event will be called automatically, thats what it is there for to begin with.
And as it seems, you try calling it from your Application_Exit, which closes all the windows ... so .... What is your problem?
Just put a breakpoint in the Window_Closing and see, that is executed automatically. If not, maybe you should add the eventhander to all the windows Window_Closing events.

Related

Handling a custom control event from the parent window [duplicate]

This question already has answers here:
How can I create a click event on a custom user control?
(3 answers)
Closed 2 years ago.
This post was edited and submitted for review 3 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I have a custom control, lets call it uc_mycontrol, inside this control, I have a button lets name it btn_demo.
So in my mainwindow.xaml , i have an instance of the uc_mycontrol. I want to use the btn_demo click event handler, but I want to declare the event handler within the mainwindow's class, rather than declaring the event handler in uc_mycontrol's class. I know that the best way to handle the click event is by defining it inside uc_mycontrol but I specifically want to handle this event on the mainwindow
In summary, I have a custom control, with a button on it. I have instantiated the custom control on a window. I want to handle the button click event within the window, rather than from within the custom control.
You can define a custom event in your uc_mycontrol. Then, on bt_demo click event, very if the custom delegate has subscribers. If yes, fire the custom event.
public partial class uc_mycontrol : UserControl
{
public delegate void MyControlClickEvent(object sender, RoutedEventArgs e);
public event MyControlClickEvent OnControlClickEvent;
public uc_mycontrol()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.OnControlClickEvent?.Invoke(sender, e);// sender = the button
//this.OnControlClickEvent?.Invoke(this, e); // sender = this control
}
}
Add your custom control to MainWindow.xaml and subscribe to the custom event.
<Window x:Class="StackOverFlowWPF.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:StackOverFlowWPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:uc_mycontrol HorizontalAlignment="Left" Height="293" Margin="89,64,0,0" VerticalAlignment="Top" Width="547"
OnControlClickEvent="uc_mycontrol_OnControlClickEvent">
</local:uc_mycontrol>
</Grid>
In your MainWindow.xaml.cs, you will have:
private void uc_mycontrol_OnControlClickEvent(object sender, RoutedEventArgs e)
{
MessageBox.Show("Message");
}

SystemEvents.PowerModeChanged event handler not being called in VSTO & WPF apps

I am developing a VSTO application-level Word AddIn and a WPF application, both need to be notified when the system goes to sleep and subsequently resumes. I have bound my event handlers to the SystemEvents.PowerModeChanged event in each application, but for some reason it still never gets called when the system goes to sleep or resumes. Just to test, I am simply trying to write to the console when the system goes to sleep. I also tried setting breakpoints, but that didn't work either; although I'm not sure if they would've anyway, given that the system is suspending applications. With either attempt, it never prints nor breaks:
VSTO Addin
void ThisAddIn_Startup(object sender, EventArgs e)
{
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(powerModeChanged);
}
public void powerModeChanged(object sender, PowerModeChangedEventArgs args)
{
Console.WriteLine("Sleeping.....");
}
WPF
internal MyControl()
{
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(powerModeChanged);
}
public void powerModeChanged(object sender, PowerModeChangedEventArgs args)
{
Console.WriteLine("Sleeping!!");
}
I have tried changing the access level of the event handlers from public to private to internal and vice-versa as well as moving the binding to other parts of the code in each application, but it didn't solve the issue. Any help would be greatly appreciated thank you!
SOLUTION: As per the comments and helpful answer, the event wasn't firing because I was running windows through a VirtualBox VM. Once my coworker ran the code on a native windows machine, it worked.
Try this:
XAML:
<Window x:Class="WpfApplication279.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:WpfApplication279"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<ListView x:Name="listView1" Margin="0">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
MainWindow:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
listView1.Items.Add(string.Format("{0} : Power mode changed = {1}", DateTime.Now, e.Mode));
}
}
In order to trigger the event in a Windows 10 machine, right-click the Start button and then:
Letting the machine go into sleep mode by timeout works the same way. These are my settings:
Same result:

Paint event does not fire when Invalidate() is called

I am working on a WPF application that has a Panel within a WindowsFormHost. The panel contains graphics that need to be redrawn every so often, and the code that draws these graphics is located within an OnPaint() event. The problem is, the OnPaint() event never seems to fire. To debug, I added a button to my form and used the button's click event handler to call the Invalidate() event. Even when I call Invalidate(), I can't seem to get the Paint event to fire. My code-behind looks like this:
public MainWindow()
{
InitializeComponent();
}
private void myPanel_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
/// Draw stuff
}
private void Button_Click(object sender, RoutedEventArgs e)
{
myPanel.Invalidate();
}
And my XAML looks like this:
<Window x:Class="MyProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Name="stackPanel">
<Button Content="Button" Click="Button_Click"/>
<WindowsFormsHost x:Name="windowsFormsHost" >
<WindowsFormsHost.Child>
<wf:Panel x:Name="myPanel" Paint="myPanel_Paint"/>
</WindowsFormsHost.Child>
</WindowsFormsHost>
</StackPanel>
</Grid>
I've read through this: WindowsFormHost Paint Event Not Firing
...but we don't seem to be having the same problem, as my XAML does reference my Paint event handler, and OnPaint() still doesn't fire.
I have already tried adding myPanel.Update() to my Button_Click event, beneath my call to myPanel.Invalidate(). That also doesn't work.
What am I doing wrong here? Is it possible that Invalidate() is not really invalidating?

Cannot drag text into a WPF window

I'm trying to set up a WPF window so that it can accept different types of data via Drag and Drop. If I make a new project and set the window to the following:
<Window x:Class="DropShare.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" AllowDrop="True" DragEnter="Window_DragEnter">
<Grid>
</Grid>
</Window>
And set the code-behind to:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_DragEnter(object sender, DragEventArgs e)
{
}
}
I only ever get DragEnter firing for files. It never fires for anything else - text, images, etc.
Is there something I'm missing? All the tutorials I've read have seemed to suggest this is all that's needed as the DragEnter event handler let's me state what I accept.
So your code works fine for me. But try this...
In your Window:
<Label Background="Purple" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Drag from here!" MouseDown="Label_MouseDown"/>
and in your code behind:
private void Label_MouseDown(object sender, MouseButtonEventArgs e)
{
DragDrop.DoDragDrop(this, "This is just a test", DragDropEffects.All);
}
Then drag from the label into the window and see if your event fires.
If this works, it may have something to do with the permissions level between Visual Studio and your outside environment (possibly).
See:
https://superuser.com/questions/59051/drag-and-drop-file-into-application-under-run-as-administrator
In WPF drag and drop feature always has to deal with DragDrop Class, Please check here how to do drag and drop across applications

UserControl Events are very slow

I have recently started to move my user controls in DLLs. These controls usually look something like this:
<UserControl x:Class="DialogBase.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Button Content="OK" Click="OkButton_Click"/>
</Grid>
</UserControl>
I want to able to use every button in the control like in a standard control. For example when somebody uses the control above, he should be able to handle the click event in an own method like this:
<lib:UserControl1
OkButtonClick="MyCostomClickMethod"
/>
I usualy achieve this like this: (code-behind file of user control)
public static RoutedEvent OkButtonClickEvent = EventManager.RegisterRoutedEvent("OkButtonClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UserControl1));
public event RoutedEventHandler OkButtonClick
{
add
{
AddHandler(OkButtonClickEvent, value);
}
remove
{
RemoveHandler(OkButtonClickEvent, value);
}
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(OkButtonClickEvent));
}
This works fine but very slow. The delay between a click and the resulting action can be up to a second. Can somebody tell me if there is a faster or in any way better way to do this?
I would create a Command in the class the you actually want the event. Then bind the Button Command to it. You can create your own Command or use something like a DelegateCommand

Categories