C# WPF PowerModeChanged doesn't work on Surface - c#

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

Related

UIElement.ManipulationDelta only Triggers Once on C# WPF

I want to implement an UI for finger controling, in WPF C# .Net framework, VS2019.
ManipulationDelta event is added on a Rectangle and it supposed to work continiously. But when I test it, it triggered only once at the moment I tapped(touch down). This event should be triggered continuously while my finger pressing.
Target: Show the position of pointer within the rectangle area.
XAML:
<Window x:Class="WpfApp5.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:WpfApp5"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="0,0,-322,-112">
<Rectangle
ManipulationDelta="Rectangle_ManipulationDelta"
TouchMove="Rectangle_TouchMove"
Fill="#FFF4F4F5"
HorizontalAlignment="Left"
Height="274" Margin="162,70,0,0"
Stroke="Black"
VerticalAlignment="Top"
Width="582" IsManipulationEnabled="True"/>
<TextBlock
x:Name="textBlock"
HorizontalAlignment="Left"
TextWrapping="Wrap"
VerticalAlignment="Top"
Margin="31,26,0,0"><Run Text="TextBlock"/></TextBlock>
</Grid>
Here is the event to print the postion of finger:
C#:
namespace WpfApp5{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
}
private void Rectangle_TouchMove(object sender, TouchEventArgs e)
{
textBlock.Text = "Manipulation Touch: " + Mouse.GetPosition(Application.Current.MainWindow).ToString();
}
}
}
UI tested on Windows10 Simulator v16 and Surface Pro
Holding right-clicking is disabled
A test video is here to describe the issue with subtitle
Test Video
After testing, the event likes TouchMove, MouseMove, ManipulationDelta will be fired only if the cursor "get into" the border of element. I want to trigger this event within target area. Or should I use another event to achieve this?
Any suggestion is appreciated! Thank you.
I found that I use worng event, I should use TouchMove instead of ManipulationDelta(manipulation means manipulation for translation, zoom, etc, it's not necessary in this case).
And the flag should be set to false:
IsManipulationEnabled="false"
It working now! And thanks for who paticipating this discussion.

WinUI ListView ObservableColellection binding not working

I'm learning the new WinUI platform together with XAML and GUI programming in C# and I'm not sure if I correctly understand how the bindings and updates work, but I can't get the following code (minimal working example) to work:
MainPage.xaml
<Page
x:Class="uitest.MainPage"
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"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<ListView ItemsSource="{x:Bind Items, Mode=OneWay}"></ListView>
<Button Content="Add" Click="Button_OnClick"></Button>
</StackPanel>
</Page>
MainPage.xaml.cs
using System.Collections.ObjectModel;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace uitest
{
public sealed partial class MainPage : Page
{
public ObservableCollection<string> Items = new ObservableCollection<string>();
public MainPage()
{
this.InitializeComponent();
Items.Add("A");
Items.Add("B");
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
Items.Add("Next");
}
}
}
When I start the application, I see a list with two items but when I click the button nothing happens. I wanted to use the Live Visual Tree for debugging but it's not working for some reason.
I opened an issue on the official WinUI repository for this and apparently it's a compatibility fault in the latest WinUI 3 preview. I should also note this does not work only on the UWP platform but it works on the Desktop (Win32).

WPF WebView doesn't show

I'm learning WPF WebView control, I have the below MainWindow.xaml file:
<Window x:Class="MyWPF.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:MyWPF"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid x:Name="Grid1" Grid.Row="1" Grid.Column="1">
<WPF:WebView x:Name="webView1"
Grid.Row="0"
Grid.Column="0"
Loaded="WebView_Loaded" />
</Grid>
</Window>
and the below corresponding MainWindow.xaml.cs file:
namespace MyWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
webView1.Navigate(new Uri("https://www.google.com"));
}
private void WebView_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
But I don't get any expecting popup window. If I remove
webView1.Navigate(new Uri("https://www.google.com"));
I can get a blank popup window. What is wrong with my code and how to solve it?
UPDATE1
I added Window_Loaded event handler and move the below two in it, now I can see a blank popup window but without any content as well as message box.
Uri uri = new Uri("https://www.google.com");
WebView1.Navigate(uri);
The whole updated code-behind:
namespace MyWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
Uri uri = new Uri("https://www.google.com");
WebView1.Navigate(uri);
}
}
}
UPDATE2
I added one HyperLink and one Button into xaml file, the below is the updated xaml file:
<Window x:Class="MyWPF.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:MyWPF"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" AllowsTransparency="False" >
<Grid x:Name="Grid1" Visibility="Visible" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="71*"/>
</Grid.ColumnDefinitions>
<WPF:WebView x:Name="WebView1" Visibility="Visible" Grid.Column="1" Margin="50,50,50,50">
</WPF:WebView>
<Button Name="BTN1" Click="BTN1_Click" Margin="285,380,285,10" Grid.Column="1" >Click Me</Button>
<TextBlock Margin="0,0,747,390" Grid.ColumnSpan="2">
<Hyperlink
NavigateUri="http://www.google.com">
Google
</Hyperlink>
</TextBlock>
</Grid>
</Window>
and adding Button click event handler into the code-behind with webview initialization inside it:
namespace MyWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
//Uri uri = ;
WebView1.Navigate(new Uri("https://www.google.com"));
}
private void BTN1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
WebView1.Navigate(new Uri("https://www.google.com"));
}
}
}
Nothing happens after clicking the HyperLink. I see popup Messagebox after clicking button but still google doesn't show up.
UPDATE3
I followed the link:
https://learn.microsoft.com/en-us/windows/communitytoolkit/controls/wpf-winforms/webview#high-dpi
I set Source property Source="http://www.google.com" inside the xaml file, see the below code:
<Window x:Class="MyWPF.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:MyWPF"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" AllowsTransparency="False" >
<Grid x:Name="Grid1" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="71*"/>
</Grid.ColumnDefinitions>
<WPF:WebView x:Name="WebView1" Visibility="Visible" Grid.Column="1" Margin="50,50,50,50" Source="http://www.google.com" >
</WPF:WebView>
<Button Name="BTN1" Click="BTN1_Click" Margin="285,380,285,10" Grid.Column="1" >Click Me</Button>
<TextBlock Margin="0,0,747,390" Grid.ColumnSpan="2">
<Hyperlink
NavigateUri="http://www.google.com">
Google
</Hyperlink>
</TextBlock>
</Grid>
</Window>
But still not working.
UPDATE4
I added((ISupportInitialize)webView).BeginInit() and ((ISupportInitialize)webView).EndInit() into the button click event handler, see the below:
using Microsoft.Toolkit.Wpf.UI.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MyWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
}
private void BTN1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
((ISupportInitialize)WebView1).BeginInit();
((ISupportInitialize)WebView1).EndInit();
WebView1.Navigate(new Uri("https://localhost:3000"));
Console.ReadLine();
}
}
}
But get the below error message at this line:
((ISupportInitialize)WebView1).BeginInit();
:
$exception {"Could not find any resources appropriate for the specified culture or the neutral culture. Make sure
\"Microsoft.Toolkit.Win32.UI.Controls.DesignerUI.resources\" was
correctly embedded or linked into assembly
\"Microsoft.Toolkit.Wpf.UI.Controls.WebView\" at compile time, or that
all the satellite assemblies required are loadable and fully
signed."} System.Resources.MissingManifestResourceException
Then I went back and added more properties based on this link:
https://github.com/rjmurillo/webview-samples/blob/master/Toolkit/dotnet/Microsoft.Toolkit.Win32.Samples.WPF.WebView/MainWindow.xaml
<WPF:WebView x:Name="WebView1" Visibility="Visible" Grid.Column="1" Margin="50,50,50,50" Source="http://www.google.com" IsIndexedDBEnabled="True"
IsJavaScriptEnabled="True"
IsPrivateNetworkClientServerCapabilityEnabled="True"
IsScriptNotifyAllowed="True" >
</WPF:WebView>
But still WebView not working.
I was having the same issue upgrading from the first preview Toolkit, and it was all because the Navigate function causing to start window hidden.
Change from:
WebView1.Navigate(new Uri("https://localhost:3000"));
To:
WebView1.Source = new Uri("https://localhost:3000");
I was also having this issue and even using the myWebBrowser.Source = new Uri("https://www.google.com"); it was not showing the page.
I added the following to the code and now it loads fine.
myWebBrowser.BringIntoView();
I am using this with WPF and displaying it in a popup window, I'm not sure if that has anything to do with the issue I was having or not.
Did you run your program as an administrator (with elevated privileges), either directly or through Visual Studio?
According to this discussion this is not possible, the Win32 WebView does not support running under an elevated token.
If you check your Windows event log, you should also find an application error like the one mentioned in the discussion.
I also tried to use WebView WPF, but it can not show when I use webview.Source = url as accepted answer.
Finally, I changed to use CefSharp.Wpf library following this link https://www.technical-recipes.com/2016/using-the-cefsharp-chromium-web-browser-in-wpf-xaml/
And it worked perfectly at my site, i shared for whom concerned.
Create a new WPF project
Obtain the CefSharp packages using NuGet
Select Tool > NuGet Package manager > Package Manager Console.
Use the PM> install-package CefSharp.Wpf
Use in WPF as
<Window x:Class="CefSharpBrowser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
Title="MainWindow"
Height="350" Width="525">
<Grid>
<wpf:ChromiumWebBrowser
x:Name="Browser"
Address="http://www.myaddress.com" />
</Grid>
</Window>

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:

How to show a preview of screen saver inside WPF window

I want to be able to show a preview of a screen saver inside WPF window. (using a container or control or ...) I know that Windows itself passes "/p" argument to the screen saver to get a preview. But how can I show that preview inside my WPF application? Should I get a handle of it and change its parent to my container o control? How?
You need to use Windows.Forms interop, because screen savers expect windows handles (HWND) and in WPF, only top-level windows have them.
MainWindow.xaml
<Window x:Class="So18547663WpfScreenSaverPreview.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="Screen Saver Preview" Height="350" Width="525"
Loaded="MainWindow_OnLoaded" Closed="MainWindow_OnClosed"
SizeToContent="WidthAndHeight">
<StackPanel Orientation="Vertical" Margin="8">
<TextBlock Text="Preview"/>
<WindowsFormsHost x:Name="host" Width="320" Height="240">
<forms:Control Width="320" Height="240"/>
</WindowsFormsHost>
</StackPanel>
</Window>
MainWindow.xaml.cs
using System;
using System.Diagnostics;
using System.Windows;
namespace So18547663WpfScreenSaverPreview
{
public partial class MainWindow
{
private Process saver;
public MainWindow ()
{
InitializeComponent();
}
private void MainWindow_OnLoaded (object sender, RoutedEventArgs e)
{
saver = Process.Start(new ProcessStartInfo {
FileName = "Bubbles.scr",
Arguments = "/p " + host.Child.Handle,
UseShellExecute = false,
});
}
private void MainWindow_OnClosed (object sender, EventArgs e)
{
// Optional. Screen savers should close themselves
// when the parent window is destroyed.
saver.Kill();
}
}
}
Assembly references
WindowsFormsIntegration
System.Windows.Forms
Related links
Walkthrough: Hosting a Windows Forms Control in WPF
Creating a Screen Saver with C# (describes command line arguments)

Categories