Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Threading.Tasks;
using Microsoft.Maui.Controls;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Hosting;
using Xunit;

namespace Microsoft.Maui.DeviceTests
Expand Down Expand Up @@ -52,6 +54,50 @@ await InvokeOnMainThreadAsync(() =>
Assert.True(platformControl.IsReadOnly);
});
}


[Fact(DisplayName = "Unfocus will work when page is shown a 2nd time")]
public async Task UnFocusOnEntryAfterPagePop()
{
int unfocused = 0;
EnsureHandlerCreated(builder =>
{
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(Toolbar), typeof(ToolbarHandler));
handlers.AddHandler(typeof(NavigationPage), typeof(NavigationViewHandler));
handlers.AddHandler<Page, PageHandler>();
handlers.AddHandler(typeof(Window), typeof(WindowHandlerStub));
handlers.AddHandler(typeof(Entry), typeof(EntryHandler));

});
});

var entry = new Entry();
entry.Unfocused += (s, e) =>
{
if(!e.IsFocused)
{
unfocused++;
}

};
var navPage = new NavigationPage(new ContentPage { Content = entry });
var window = new Window(navPage);

await CreateHandlerAndAddToWindow<WindowHandlerStub>(window, async (handler) =>
{
entry.Focus();
await Task.Delay(500);
Comment thread
rmarinho marked this conversation as resolved.
Outdated
entry.Unfocus();
await navPage.PushAsync(new ContentPage());
await navPage.PopAsync();
entry.Focus();
await Task.Delay(500);
entry.Unfocus();
Assert.True(unfocused == 2);
});
}
#endif

[Theory(DisplayName = "CursorPosition Initializes Correctly")]
Expand Down
43 changes: 20 additions & 23 deletions src/Core/src/Platform/Windows/ViewExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ namespace Microsoft.Maui.Platform
{
public static partial class ViewExtensions
{
internal static Page? ContainingPage; // Cache of containing page used for unfocusing

public static void TryMoveFocus(this FrameworkElement platformView, FocusNavigationDirection direction)
{
if (platformView?.XamlRoot?.Content is UIElement elem)
Expand Down Expand Up @@ -368,34 +366,33 @@ internal static void UnfocusControl(Control control)
// hack. What we *can* do is set the focus to the Page which contains Control;
// this will cause Control to lose focus without shifting focus to, say, the next Entry

if (ContainingPage == null)
{
// Work our way up the tree to find the containing Page
DependencyObject parent = control;

while (parent != null && parent is not Page)
{
parent = VisualTreeHelper.GetParent(parent);
}
// Work our way up the tree to find the containing Page
// We can't cache this parent because this Page can be disposed
// or the Control can belong to another page
DependencyObject parent = control;

ContainingPage = parent as Page;
while (parent != null && parent is not Page)
Comment thread
rmarinho marked this conversation as resolved.
Outdated
{
parent = VisualTreeHelper.GetParent(parent);
}

if (ContainingPage != null)
{
// Cache the tabstop setting
var wasTabStop = ContainingPage.IsTabStop;
if (parent is not Page containingPage)
return;

// Controls can only get focus if they're a tabstop
ContainingPage.IsTabStop = true;
ContainingPage.Focus(FocusState.Programmatic);
// Cache the tabstop setting
var wasTabStop = containingPage.IsTabStop;

// Restore the tabstop setting; that may cause the Page to lose focus,
// but it won't restore the focus to Control
ContainingPage.IsTabStop = wasTabStop;
}
// Controls can only get focus if they're a tabstop
containingPage.IsTabStop = true;
containingPage.Focus(FocusState.Programmatic);

// Restore the tabstop setting; that may cause the Page to lose focus,
// but it won't restore the focus to Control
containingPage.IsTabStop = wasTabStop;
}



internal static IWindow? GetHostedWindow(this IView? view)
=> GetHostedWindow(view?.Handler?.PlatformView as FrameworkElement);

Expand Down