Skip to content

Commit 711ce1e

Browse files
Update FocusTracker to no longer use a DispatcherQueueTimer to constantly look for focused element
Fixes #3884 Now uses FocusManager.GotFocus event from 1809 (new min SDK version)
1 parent cfbb29d commit 711ce1e

File tree

1 file changed

+33
-34
lines changed

1 file changed

+33
-34
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();

0 commit comments

Comments
 (0)