Changing the mouse cursor in WinUI 3. #1816
-
With the release of the 1.0 Windows App SDK and WinUI 3 (Congrats team), I've been experimenting with porting our application from UWP to the App SDK. The one stumbling block I've had getting it to a state where it will compile is changing the mouse cursor. The release notes for the stable channel mention that there are new APIs for changing the cursor bitmap. From what I've been able to gather, I can set the cursor by using an InputPointerSource, and setting the Cursor property on it. pointer.Cursor = InputSystemCursor.Create(InputSystemCursorShape.IBeam); My issue however is how to actually get a reference to the InputPointerSource, the documentation seems to specifically mention a XamlSwapChain which I didn't think I would need, and Intellisense tells me I can call InputPointerSource.FromAbi(IntPtr) or perhaps new InputPointerSource(IObjectReference) alternatively, I checked the properties of TappedRoutedEventArgs and PointerRoutedEventArgs and I'm able to get a PointerId from the latter and nothing from the former. Ideally, there would be a mechanism to set the cursor for any pointer over my Window (or AppWindow) Any guidance would be appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 19 comments 18 replies
-
A way is to call set_ProtectedCursor with System.Reflection, A test with Microsoft.UI.Input.InputSystemCursorShape.Hand : |
Beta Was this translation helpful? Give feedback.
-
@kevinguo305 can you help answer this question? I think it's in your area path? |
Beta Was this translation helpful? Give feedback.
-
Getting the CoreCursor from InputPointerSource is not the recommended way. We've added this new API:
and we recommend instead that you subclass the UI element that you want the cursor to be changed in, and add a method that sets a ProtectedCursor property which is part of every UIElement in WinUI 3.
Afterwards, in your main Microsoft.UI.Xaml.Controls.Page class, you can call the subclassed UI Element.ChangeCursor(InputSystemCursor.Create(*insert InputSystemCursorShape enum value*)); |
Beta Was this translation helpful? Give feedback.
-
That's all well and good. However, surely this is a style thing and it should be able to be set in a style, possibly using a visual state change. |
Beta Was this translation helpful? Give feedback.
-
[benkuhn- redacted by request of the author, but leaving as placeholder because the comment is still useful / relevant]
|
Beta Was this translation helpful? Give feedback.
-
@legistek, for transparency's sake (and to help you to make a better decision for your product), I want to clarify that It's not part of the current WinAppSDK 1.2 engineering plan to expose a XAML property to change the cursor. It's in our backlog, but it was moved out of 1.2. |
Beta Was this translation helpful? Give feedback.
-
Well you can, but one needs to subclass every control in the universe. You could also use reflection to get to the protected cursor which shouldn't be done for a production system.
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: Peter Moore ***@***.***>
Sent: Tuesday, June 14, 2022 5:16:26 AM
To: microsoft/WindowsAppSDK ***@***.***>
Cc: devmikew ***@***.***>; Comment ***@***.***>
Subject: Re: [microsoft/WindowsAppSDK] Changing the mouse cursor in WinUI 3. (Discussion #1816)
Wait - so you can't actually change the hover cursor for a control just through XAML? WTH?
—
Reply to this email directly, view it on GitHub<#1816 (reply in thread)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKBBNIKLAXGWNDI4LGNJRO3VO6CIVANCNFSM5IG7GESQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
That's not the only thing that's crazy, eg, look at the Window class, its the top level control in the system and its not even a dependency object.
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: Peter Moore ***@***.***>
Sent: Tuesday, June 14, 2022 5:24:56 AM
To: microsoft/WindowsAppSDK ***@***.***>
Cc: devmikew ***@***.***>; Comment ***@***.***>
Subject: Re: [microsoft/WindowsAppSDK] Changing the mouse cursor in WinUI 3. (Discussion #1816)
There seems to be an extension property FrameworkElementExtensions.Cursor in the community toolkit but it doesn't seem to do anything.
After less than a day of attempting to explore porting my WPF app to WinUI it's painfully obvious this thing is not ready for prime time. Not even close. I might as well just make a PWA. I don't understand what Microsoft is thinking making this SDK so unusable on so many levels.
—
Reply to this email directly, view it on GitHub<#1816 (reply in thread)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKBBNIMORIJF3U2YP5SGJODVO6DIRANCNFSM5IG7GESQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
@devmikew If you have to subclass every control in your app to get this behavior, it's clear to me that the framework is not given you the right set of features for your scenario. Although I have seen companies that subclass every control because they add them their special sauce. But this should be the expectation, not the rule. |
Beta Was this translation helpful? Give feedback.
-
The only way I've been able to do this is by using reflection.
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: asierpn ***@***.***>
Sent: Friday, August 19, 2022 9:20:05 PM
To: microsoft/WindowsAppSDK ***@***.***>
Cc: devmikew ***@***.***>; Mention ***@***.***>
Subject: Re: [microsoft/WindowsAppSDK] Changing the mouse cursor in WinUI 3. (Discussion #1816)
And how can we do this with TextBlock if it is sealed?
—
Reply to this email directly, view it on GitHub<#1816 (reply in thread)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKBBNIKRIJUDWKZVL43N2JDVZ5UWLANCNFSM5IG7GESQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Yes, reflection is the only way I've found to do it, I've created an extension method:
And a behavior:
|
Beta Was this translation helpful? Give feedback.
-
Good, thanks for your code.
If anyone at MS is watching, please fix this.
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: asierpn ***@***.***>
Sent: Friday, August 19, 2022 9:45:19 PM
To: microsoft/WindowsAppSDK ***@***.***>
Cc: devmikew ***@***.***>; Mention ***@***.***>
Subject: Re: [microsoft/WindowsAppSDK] Changing the mouse cursor in WinUI 3. (Discussion #1816)
Yes, reflection is the only way I've found to do it, I've created an extension method:
public static void ChangeCursor(this UIElement uiElement, InputCursor cursor)
{
Type type = typeof(UIElement);
type.InvokeMember("ProtectedCursor", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, uiElement, new object[] { cursor });
}
And a behavior:
public static readonly DependencyProperty CursorProperty = DependencyProperty.Register("Cursor", typeof(InputSystemCursorShape), typeof(CursorBehavior), new PropertyMetadata(InputSystemCursorShape.Arrow));
public InputSystemCursorShape Cursor
{
get
{
return (InputSystemCursorShape)GetValue(CursorProperty);
}
set
{
SetValue(CursorProperty, value);
SetCursor();
}
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObject_Loaded;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
private bool _loaded;
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
_loaded = true;
SetCursor();
}
private void SetCursor()
{
if (!_loaded)
return;
AssociatedObject.ChangeCursor(InputSystemCursor.Create(Cursor));
}
—
Reply to this email directly, view it on GitHub<#1816 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKBBNIOJH2ZOVC4MAXUJDBLVZ5XU7ANCNFSM5IG7GESQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Why not make a |
Beta Was this translation helpful? Give feedback.
-
Yes, that is also possible, but eventually you will have to subclass all controls. If not you then across all developers. If smells a fair bit .
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: Peter Moore ***@***.***>
Sent: Monday, August 22, 2022 10:30:19 PM
To: microsoft/WindowsAppSDK ***@***.***>
Cc: devmikew ***@***.***>; Mention ***@***.***>
Subject: Re: [microsoft/WindowsAppSDK] Changing the mouse cursor in WinUI 3. (Discussion #1816)
Why not make a Border subclass that exposes a cursor dependency property and wrap anything with it whose cursor you need to change through binding?
—
Reply to this email directly, view it on GitHub<#1816 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKBBNIIV55PAGIBBKPZDW4DV2NXFXANCNFSM5IG7GESQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Is there anything simpler meanwhile? I love WinUI looks but it makes everything so complicated ^^ |
Beta Was this translation helpful? Give feedback.
-
How can I change cursor to specific image (for ex: pen.cur), I added pen.cur as an embedded resource, and used InputDesktopResourceCursor.Create(uint resourceId), but I have no ideal to find the resourceId of pen.cur. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
@kevinguo305 Thanks for clarifying the intended mechanism, but I think as you can see from this thread, having to subclass the control isn't really an acceptable solution to a lot of users/cases. What's the thinking about how 3rd party controls (that might be sealed, etc.) could be controlled in that way, or MAUI for example? Custom cursors were/are so easy in WinForms, and just so unnecessarily hard in WinUI. |
Beta Was this translation helpful? Give feedback.
-
As well as in code.Sent from my Galaxy
-------- Original message --------From: vmiguelangmsft ***@***.***> Date: 16/12/24 11:19 (GMT+10:00) To: microsoft/WindowsAppSDK ***@***.***> Cc: devmikew ***@***.***>, Mention ***@***.***> Subject: Re: [microsoft/WindowsAppSDK] Changing the mouse cursor in WinUI 3. (Discussion #1816)
Exactly! it should be in Styles
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
Getting the CoreCursor from InputPointerSource is not the recommended way. We've added this new API:
and we recommend instead that you subclass the UI element that you want the cursor to be changed in, and add a method that sets a ProtectedCursor property which is part of every UIElement in WinUI 3.
Afterwards, in your main Microsoft.UI.Xaml.Controls.Page class, you can call the subclassed UI Element.ChangeCursor(InputSystemCursor.Create(*insert InputSystemCursorShape enum value*));