Skip to content

Commit ce53551

Browse files
Merge pull request #3888 from michael-hawker/focus-tracker
Fix for FocusTracker Sample App hang
2 parents 5fd1e5d + 43128c0 commit ce53551

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

Microsoft.Toolkit.Uwp.DeveloperTools/FocusTracker/FocusTracker.cs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ public partial class FocusTracker : Control
3434

3535
private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
3636
{
37-
var focusTracker = d as FocusTracker;
38-
39-
if (e.NewValue != null && (bool)e.NewValue)
37+
if (d is FocusTracker focusTracker)
4038
{
41-
focusTracker?.Start();
42-
}
43-
else
44-
{
45-
focusTracker?.Stop();
39+
if (e.NewValue != null && (bool)e.NewValue)
40+
{
41+
focusTracker.Start();
42+
}
43+
else
44+
{
45+
focusTracker.Stop();
46+
}
4647
}
4748
}
4849

49-
private DispatcherQueueTimer updateTimer;
5050
private TextBlock controlName;
5151
private TextBlock controlType;
5252
private TextBlock controlAutomationName;
@@ -69,32 +69,42 @@ public FocusTracker()
6969
DefaultStyleKey = typeof(FocusTracker);
7070
}
7171

72+
/// <summary>
73+
/// Update the visual state of the control when its template is changed.
74+
/// </summary>
75+
protected override void OnApplyTemplate()
76+
{
77+
controlName = GetTemplateChild("ControlName") as TextBlock;
78+
controlType = GetTemplateChild("ControlType") as TextBlock;
79+
controlAutomationName = GetTemplateChild("ControlAutomationName") as TextBlock;
80+
controlFirstParentWithName = GetTemplateChild("ControlFirstParentWithName") as TextBlock;
81+
}
82+
7283
private void Start()
7384
{
74-
if (updateTimer == null)
85+
// Get currently focused control once when we start
86+
if (Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot") && XamlRoot != null)
7587
{
76-
updateTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
77-
updateTimer.Tick += UpdateTimer_Tick;
88+
FocusOnControl(FocusManager.GetFocusedElement(XamlRoot) as FrameworkElement);
89+
}
90+
else
91+
{
92+
FocusOnControl(FocusManager.GetFocusedElement() as FrameworkElement);
7893
}
7994

80-
updateTimer.Start();
95+
// Then use FocusManager event from 1809 to listen to updates
96+
FocusManager.GotFocus += FocusManager_GotFocus;
8197
}
8298

8399
private void Stop()
84100
{
85-
updateTimer?.Stop();
101+
FocusManager.GotFocus -= FocusManager_GotFocus;
86102
ClearContent();
87103
}
88104

89-
/// <summary>
90-
/// Update the visual state of the control when its template is changed.
91-
/// </summary>
92-
protected override void OnApplyTemplate()
105+
private void FocusManager_GotFocus(object sender, FocusManagerGotFocusEventArgs e)
93106
{
94-
controlName = GetTemplateChild("ControlName") as TextBlock;
95-
controlType = GetTemplateChild("ControlType") as TextBlock;
96-
controlAutomationName = GetTemplateChild("ControlAutomationName") as TextBlock;
97-
controlFirstParentWithName = GetTemplateChild("ControlFirstParentWithName") as TextBlock;
107+
FocusOnControl(e.NewFocusedElement as FrameworkElement);
98108
}
99109

100110
private void ClearContent()
@@ -105,19 +115,8 @@ private void ClearContent()
105115
controlFirstParentWithName.Text = string.Empty;
106116
}
107117

108-
private void UpdateTimer_Tick(object sender, object e)
118+
private void FocusOnControl(FrameworkElement focusedControl)
109119
{
110-
FrameworkElement focusedControl;
111-
112-
if (Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot") && XamlRoot != null)
113-
{
114-
focusedControl = FocusManager.GetFocusedElement(XamlRoot) as FrameworkElement;
115-
}
116-
else
117-
{
118-
focusedControl = FocusManager.GetFocusedElement() as FrameworkElement;
119-
}
120-
121120
if (focusedControl == null)
122121
{
123122
ClearContent();

Microsoft.Toolkit.Uwp.SampleApp/App.xaml.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Threading.Tasks;
67
using Microsoft.Toolkit.Uwp.Helpers;
78
using Microsoft.Toolkit.Uwp.SampleApp.Common;
89
using Microsoft.Toolkit.Uwp.SampleApp.SamplePages;
@@ -163,7 +164,7 @@ private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
163164
/// </summary>
164165
/// <param name="sender">The source of the suspend request.</param>
165166
/// <param name="e">Details about the suspend request.</param>
166-
private void OnSuspending(object sender, SuspendingEventArgs e)
167+
private async void OnSuspending(object sender, SuspendingEventArgs e)
167168
{
168169
var deferral = e.SuspendingOperation.GetDeferral();
169170

@@ -179,7 +180,18 @@ private void OnSuspending(object sender, SuspendingEventArgs e)
179180
// ignore
180181
}
181182

182-
deferral.Complete();
183+
try
184+
{
185+
await Task.Delay(2000);
186+
}
187+
catch
188+
{
189+
// ignore
190+
}
191+
finally
192+
{
193+
deferral.Complete();
194+
}
183195
}
184196
}
185197
}

0 commit comments

Comments
 (0)