'UWP control to keep focus after mouse click
I have a canvas (technically a SkiaSharp SKXamlCanvas) that I need to host in a control that can get focus (for reasons I won't go into here). I added the canvas as a child to a class (call it ControlHost) derived from ContentControl and set the canvas as the Content. The ControlHost's GetFocus gets called when I open the app, but when I click on the ControlHost (which takes up the whole window), I get a LostFocus after releasing the mouse button.
I know things like TextBox keep focus after clicking on them with the mouse. Is there another control I can use that will keep focus and simply act as a container for my canvas? I've tried UserControl, Frame, Page, etc. Or maybe there are properties I can set on a ContentControl that will allow it to keep focus?
This can easily be reproduced by making a blank UWP app and adding the following control as a child to the grid of MainPage.
public class ContentControlTest : ContentControl
{
public ContentControlTest()
{
GotFocus += OnGotFocus;
LostFocus += OnLostFocus;
}
private void OnLostFocus(object sender, RoutedEventArgs e)
{
Debug.WriteLine("OnLostFocus");
}
private void OnGotFocus(object sender, RoutedEventArgs e)
{
Debug.WriteLine("OnGotFocus");
}
}
Solution 1:[1]
UWP control to keep focus after mouse click
It is by-desgin that ContentControl will lost focus when PointerReleased. The ContentControl inherit from Control. so it has Focus method, if you want to keep focus, you could try to call Focus method in OnLostFocus like following.
private void OnLostFocus(object sender, RoutedEventArgs e)
{
Debug.WriteLine("OnLostFocus");
this.Focus(FocusState.Programmatic);
}
Solution 2:[2]
Actually, you can keep focus after clicking on a ContentControl.
By default, after the ContentControl's PointerReleased event is triggered, the ContentControl's LostFocus event is triggered (a control loses focus when another one gets it).
Thus, you can modify the default behavior by adding a custom PointerReleased event handler to the ContentControl. Since PointerReleased is a routed event, you simply need to add e.Handled = true.
private void ControlHost_PointerReleased(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nico Zhu - MSFT |
| Solution 2 | Jess Rod |
