maui
maui copied to clipboard
[WinUI] First Entry/Editor gets focus if put inside ScrollView
Description
On WinUI platform, if Entry or Editor are put inside a ScrollView, they do not lose focus correctly on click on empty space or other non-focusable elements. Instead, the first Entry or Editor is focused. This same bug was earlier present in Xamarin.Forms (and is still open): https://github.com/xamarin/Xamarin.Forms/issues/10420
Steps to Reproduce
- Create a MAUI App from template
- In MainPage inside the VerticalStackLayout put: Entry and/or Editor, some unfocusable element like Label/ContentView and Button. (VerticalStackLayout is already in ScrollView in the template)
- Focus entry or editor
- Click on empty space inside ScrollView or on ContentView
Link to public reproduction project repository
https://github.com/maiia-kuzmishyna/MAUI-EntryScrollViewFocus
Version with bug
6.0.400
Last version that worked well
Unknown/Other
Affected platforms
Windows
Affected platform versions
Windows 11 (SDK 10.0.19041.0)
Did you find any workaround?
I didn't find any universal workaround, however focus is lost properly on click on Button / other focusable controls.
Relevant log output
No response
Depends on
- [ ] https://github.com/microsoft/microsoft-ui-xaml/issues/597
VS bug #1831157
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
It looks like this is a WinUI issue
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
We could potentially work around this by doing something like this? https://stackoverflow.com/questions/49713033/uwp-scrollviewer-unexpected-behavior
Maybe we can change the default style yo have this ContentControl in the actual control... Not sure how that would work.
Verified this on Visual Studio Enterprise 17.7.0 Preview 1.0. This issue does not repro on Android 13.0-API33, repro on Windows 11 with sample Project: FocusSpike.zip
I've found a pretty clean workaround using a handler mapping:
ScrollViewHandler.Mapper.AppendToMapping(nameof(IScrollView.Content), MapContent);
private static void MapContent(IScrollViewHandler handler, IScrollView view)
{
if (handler.PlatformView == null || handler.MauiContext == null
|| view.PresentedContent == null || handler.PlatformView.Content is not ContentPanel)
{
return;
}
// Maui always puts the ScrollView content into a ContentPanel.
// Setting IsTabStop = true on the panel prevents us from running into
// https://github.com/dotnet/maui/issues/11472
var panel = (ContentPanel)handler.PlatformView.Content;
panel.IsTabStop = true;
}
@Felicity-R Is there any known issue with the workaround, please? I mean does it break something?
@Felicity-R Is there any known issue with the workaround, please? I mean does it break something?
Nothing I've come across. I suppose it would impact tab keyboard navigation since it's making the container a tab stop, so if keyboard navigation is important in your app you should test to see if that change is a problem for you.
Very simple very easy fix that works. found this https://stackoverflow.com/questions/42231163/is-it-possible-to-stop-the-first-entry-getting-focus-in-a-scrollview-in-xamarin and mentions
_In UWP it is by design that when the StackLayout gets tapped the system will search element for-each in the StackLayout until the first one which can be focused on. As a workaround to solve this issue, you can place an invisible buton in the top of StackLayout.
<ScrollView>
<StackLayout>
<Button HeightRequest="0" WidthRequest="1" />
<Entry />
....
<Entry />
</StackLayout>
</ScrollView>
The button will be focused on when StackLayout was tapped. The Entry will not be focused_
It seems this issue is related to the WinUI3. You can take a look at WinUI 3 Gallery App to see this behavior.
All the panels are focusable and deliver focus logic to their children recursively. When you click a container, it automatically delivers focus to the first nearest focusable child such as TextBox like in this case.
If you disable focusing for the parent panel (StackLayout), then the entries inside StackLayout can't be focused anymore even by clicking on it.
#if WINDOWS
stackLayout.HandlerChanged+= (s,e)=>
{
if (stackLayout.Handler.PlatformView is Microsoft.Maui.Platform.LayoutPanel panel)
{
panel.AllowFocusOnInteraction = false;
panel.GettingFocus += (s, e) =>
{
e.Cancel = true;
};
}
};
#endif
It looks like this is a WinUI issue
The issue was closed as fixed in WinAppSDK 1.6 three weeks ago. However, WinAppSDK 1.6 is expected to be released 6 months after 1.5 which was released 3 weeks ago. So there should be a fix in ~5 months.
We have Grid as a parent and have 2 entries and 1 button. Whenever the page appears, the entry gets focused in Windows.
The first button gets focused when we navigate and return to the same page.