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

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:

Related

WPF call Window_Closing event from code behind

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.

C# WPF PowerModeChanged doesn't work on Surface

Testing the code bellow in a non-surface device works just fine but when I try in a surface, I only get notifications when I remove the power cable ('statusChange' powerMode is triggered). Putting the surface in SLEEP the handler it's not called ('resume' and 'suspend' powerModes are not being trigged).
Anyone knows why ? Thank you.
Surface specs:
OS Name: Microsoft Windows 10 Pro
Version: 10.0.17134 Compilação 17134
OS Manufacturer: Microsoft Corporation
System Manufacturer: Microsoft Corporation
System Model: Surface Pro
System Type: x64-based PC
System SKU: Surface_Pro_1796
Example [WPF Visual Studio Pro 2015]
MainWindow:
using System;
using System.Windows;
using Microsoft.Win32;
namespace WpfApplication2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
}
private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
listView1.Items.Add(string.Format("{0} : Power mode changed = {1}", DateTime.Now, e.Mode));
}
}
}
XAML
<Window x:Class="WpfApplication2.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:WpfApplication2"
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>
</Window>
I am also working on such a problem. From what I've read, the Surface supports "Sleep state(Modern Standby)", or S0 low-power, and is not yet in actual sleep state (S1-3). Pressing the power button or clicking the "sleep" option from the windows menu does not enter sleep directly but enters S0 low-power instead, thus not triggering PowerModeChanged.
https://learn.microsoft.com/en-us/windows/desktop/power/system-power-states#sleep-state-modern-standby

WPF controls do not behave as expected with multi-touch

I am creating an application in WPF that relies on multi-touch and, although I can receive multiple touch points, the WPF controls do not behave as expected when multiple touches occur at the same time.
I created a simple test WPF application using buttons for visualization to ensure it wasn't anything in my project causing the issue.
The XAML:
<Window x:Class="TouchSample3.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:TouchSample3"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid TouchDown="Grid_TouchDown">
<Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="108,86,0,0" VerticalAlignment="Top" Width="70" Height="70" Click="button1_Click" TouchDown="button1_TouchDown"/>
<Button x:Name="button2" Content="Button" HorizontalAlignment="Left" Margin="322,86,0,0" VerticalAlignment="Top" Width="70" Height="70" Click="button2_Click" TouchDown="button2_TouchDown"/>
</Grid>
</Window>
and here is my MainWindow:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("Button 1 clicked.");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("Button 2 clicked.");
}
// TouchDown events
private void button1_TouchDown(object sender, TouchEventArgs e)
{
Console.WriteLine("Button 1 Touch Down.");
}
private void button2_TouchDown(object sender, TouchEventArgs e)
{
Console.WriteLine("Button 2 Touch Down.");
}
}
When I perform a single touch on either button it fires as expected, the TouchDown event, and Click event along with the button animation occur.
However, when I attempt to do two touches simultaneously (one finger held down, another one pressing), the TouchDown events get fired but the the Click events and the button animations do not happen.
It clearly registers the touch points but I don't understand why it doesn't perform actions/events to the WPF controls when touches happen simultaneously.
Any help or direction would be appreciated.
I think thats because the old version of Click event is not prepared well for a multi-touch wpf application. It is primary classified as a mouse event, since the TouchDown is touch event primary so it support the multi-touch feature.

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