diff --git a/SafeExamBrowser.I18n.Contracts/TextKey.cs b/SafeExamBrowser.I18n.Contracts/TextKey.cs
index d9487b8f..88b97412 100644
--- a/SafeExamBrowser.I18n.Contracts/TextKey.cs
+++ b/SafeExamBrowser.I18n.Contracts/TextKey.cs
@@ -37,7 +37,10 @@ namespace SafeExamBrowser.I18n.Contracts
BrowserWindow_MenuButton,
BrowserWindow_ReloadButton,
BrowserWindow_UrlTextBox,
+ BrowserWindow_ZoomLevelReset,
BrowserWindow_ZoomMenuItem,
+ BrowserWindow_ZoomMenuMinus,
+ BrowserWindow_ZoomMenuPlus,
Build,
ExamSelectionDialog_Cancel,
ExamSelectionDialog_Message,
diff --git a/SafeExamBrowser.I18n/Data/de.xml b/SafeExamBrowser.I18n/Data/de.xml
index 31b9d6e6..048c31d9 100644
--- a/SafeExamBrowser.I18n/Data/de.xml
+++ b/SafeExamBrowser.I18n/Data/de.xml
@@ -69,9 +69,18 @@
URL eingeben
+
+ Seiten-Zoom bei %%ZOOM%% %. Klicken zum Zurücksetzen.
+
Seiten-Zoom
+
+ Zoom vergrössern
+
+
+ Zoom verkleinern
+
Build
diff --git a/SafeExamBrowser.I18n/Data/en.xml b/SafeExamBrowser.I18n/Data/en.xml
index 12fc3ff5..99604379 100644
--- a/SafeExamBrowser.I18n/Data/en.xml
+++ b/SafeExamBrowser.I18n/Data/en.xml
@@ -69,9 +69,18 @@
Enter URL
+
+ Page Zoom at %%ZOOM%% %. Click to Reset.
+
Page Zoom
+
+ Increase Page Zoom
+
+
+ Decrease Page Zoom
+
Build
diff --git a/SafeExamBrowser.I18n/Data/fr.xml b/SafeExamBrowser.I18n/Data/fr.xml
index 3d46b4d1..ea2fcb68 100644
--- a/SafeExamBrowser.I18n/Data/fr.xml
+++ b/SafeExamBrowser.I18n/Data/fr.xml
@@ -69,9 +69,18 @@
Entrer l'URL
+
+ Zoom de la page à %%ZOOM%% %. Cliquer pour réinitialiser.
+
Zoom de la page
+
+ Augmenter zoom
+
+
+ Diminuer zoom
+
Build
diff --git a/SafeExamBrowser.I18n/Data/it.xml b/SafeExamBrowser.I18n/Data/it.xml
index 02ef95b2..3a080e4a 100644
--- a/SafeExamBrowser.I18n/Data/it.xml
+++ b/SafeExamBrowser.I18n/Data/it.xml
@@ -69,9 +69,18 @@
Inserisci URL
+
+ Zoom della pagina al %%ZOOM%% %. Fare clic per ripristinare.
+
Zoom della pagina
+
+ Aumentare zoom
+
+
+ Diminuire zoom
+
Build
diff --git a/SafeExamBrowser.I18n/Data/zh.xml b/SafeExamBrowser.I18n/Data/zh.xml
index 5c4521b2..cc0e9580 100644
--- a/SafeExamBrowser.I18n/Data/zh.xml
+++ b/SafeExamBrowser.I18n/Data/zh.xml
@@ -66,9 +66,18 @@
输入网址
+
+ 页面缩放为 %%ZOOM%% %。点击重置。
+
页面缩放
+
+ 增加页面缩放
+
+
+ 减少页面缩放
+
生成
diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/NetworkControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/NetworkControl.xaml.cs
index 92c3c950..4a5beafd 100644
--- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/NetworkControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/NetworkControl.xaml.cs
@@ -121,6 +121,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
{
Button.ToolTip = text;
Text.Text = text;
+ Button.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text);
}
private UIElement GetWirelessIcon(int signalStrength)
diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/PowerSupplyControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/PowerSupplyControl.xaml.cs
index 16241d6c..32dfdd95 100644
--- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/PowerSupplyControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/PowerSupplyControl.xaml.cs
@@ -87,6 +87,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
PowerPlug.Visibility = status.IsOnline ? Visibility.Visible : Visibility.Collapsed;
Text.Text = tooltip;
Warning.Visibility = status.BatteryChargeStatus == BatteryChargeStatus.Critical ? Visibility.Visible : Visibility.Collapsed;
+ this.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, tooltip);
}
private void RenderCharge(double charge, BatteryChargeStatus status)
diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/NetworkControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/NetworkControl.xaml.cs
index aede61e4..3832f57e 100644
--- a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/NetworkControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/NetworkControl.xaml.cs
@@ -88,6 +88,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
{
WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name);
+ Button.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, Button.ToolTip as string);
}
WirelessNetworksStackPanel.Children.Add(button);
diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/PowerSupplyControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/PowerSupplyControl.xaml.cs
index 227a287d..7c80bb12 100644
--- a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/PowerSupplyControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/PowerSupplyControl.xaml.cs
@@ -8,7 +8,6 @@
using System;
using System.Windows;
-using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
@@ -102,7 +101,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
Button.ToolTip = tooltip;
PowerPlug.Visibility = status.IsOnline ? Visibility.Visible : Visibility.Collapsed;
Warning.Visibility = status.BatteryChargeStatus == BatteryChargeStatus.Critical ? Visibility.Visible : Visibility.Collapsed;
- AutomationProperties.SetHelpText(this, Button.ToolTip as string);
+ this.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, tooltip);
}
private void RenderCharge(double charge, BatteryChargeStatus status)
diff --git a/SafeExamBrowser.UserInterface.Desktop/Windows/BrowserWindow.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Windows/BrowserWindow.xaml.cs
index 45d07e82..ddf32010 100644
--- a/SafeExamBrowser.UserInterface.Desktop/Windows/BrowserWindow.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Desktop/Windows/BrowserWindow.xaml.cs
@@ -11,6 +11,7 @@ using System.ComponentModel;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Automation;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interop;
@@ -196,7 +197,12 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
public void UpdateZoomLevel(double value)
{
- Dispatcher.Invoke(() => ZoomLevel.Text = $"{value}%");
+ Dispatcher.Invoke(() =>
+ {
+ ZoomLevel.Text = $"{value}%";
+ var zoomButtonHelpText = this.text.Get(TextKey.BrowserWindow_ZoomLevelReset).Replace("%%ZOOM%%", value.ToString("0"));
+ ZoomResetButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, zoomButtonHelpText);
+ });
}
private void BrowserWindow_Closing(object sender, CancelEventArgs e)
@@ -297,6 +303,12 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
}
}
}
+
+ if (e.Key == Key.Escape && MenuPopup.IsOpen)
+ {
+ MenuPopup.IsOpen = false;
+ MenuButton.Focus();
+ }
}
///
@@ -586,9 +598,13 @@ if (typeof __SEB_focusElement === 'undefined') {
private void LoadText()
{
DeveloperConsoleText.Text = text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem);
+ DeveloperConsoleButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem));
FindCaseSensitiveCheckBox.Content = text.Get(TextKey.BrowserWindow_FindCaseSensitive);
FindMenuText.Text = text.Get(TextKey.BrowserWindow_FindMenuItem);
+ FindMenuButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_FindMenuItem));
ZoomText.Text = text.Get(TextKey.BrowserWindow_ZoomMenuItem);
+ ZoomInButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_ZoomMenuPlus));
+ ZoomOutButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_ZoomMenuMinus));
ReloadButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_ReloadButton));
BackwardButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_BackwardButton));
ForwardButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_ForwardButton));
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml
index b48391c9..b6078b25 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml
@@ -5,7 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls"
- mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
+ mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250" IsTabStop="True">
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml
index 5e6f62a2..e540cfa7 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml
@@ -16,7 +16,7 @@
-
+
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs
index 8ff5c7e1..eeed1afd 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs
@@ -41,7 +41,14 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
InitializeLayouts();
keyboard.LayoutChanged += Keyboard_LayoutChanged;
- Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
+ Button.Click += (o, args) =>
+ {
+ Popup.IsOpen = !Popup.IsOpen;
+ this.Dispatcher.BeginInvoke((System.Action) (() =>
+ {
+ LayoutsStackPanel.Children[0].Focus();
+ }));
+ };
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
@@ -90,5 +97,14 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
Text.Text = layout.CultureName;
Button.ToolTip = tooltip;
}
+
+ private void Popup_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ if (e.Key == System.Windows.Input.Key.Enter || e.Key == System.Windows.Input.Key.Escape)
+ {
+ Popup.IsOpen = false;
+ Button.Focus();
+ }
+ }
}
}
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/NetworkControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/NetworkControl.xaml.cs
index f1b1352f..4b50365a 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/NetworkControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/NetworkControl.xaml.cs
@@ -121,6 +121,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
{
Button.ToolTip = text;
Text.Text = text;
+ Button.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text);
}
private UIElement GetWirelessIcon(int signalStrength)
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/PowerSupplyControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/PowerSupplyControl.xaml.cs
index c2a5ecfa..4985f0bb 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/PowerSupplyControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/PowerSupplyControl.xaml.cs
@@ -87,6 +87,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
PowerPlug.Visibility = status.IsOnline ? Visibility.Visible : Visibility.Collapsed;
Text.Text = tooltip;
Warning.Visibility = status.BatteryChargeStatus == BatteryChargeStatus.Critical ? Visibility.Visible : Visibility.Collapsed;
+ this.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, tooltip);
}
private void RenderCharge(double charge, BatteryChargeStatus status)
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml
index 12d82ce2..a17d3fe5 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml
@@ -16,7 +16,7 @@
-
+
@@ -24,7 +24,7 @@
-
@@ -37,7 +37,7 @@
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml.cs
index 0059ef1c..350f94d5 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/AudioControl.xaml.cs
@@ -60,6 +60,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
{
Background = Brushes.LightGray;
Button.Background = Brushes.LightGray;
+ Volume.Focus();
};
Popup.Closed += (o, args) =>
@@ -167,5 +168,23 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
return IconResourceLoader.Load(resource);
}
+
+ private void Popup_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ if (e.Key == System.Windows.Input.Key.Escape)
+ {
+ Popup.IsOpen = false;
+ Button.Focus();
+ }
+ }
+
+ private void Volume_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ if (e.Key == System.Windows.Input.Key.Enter)
+ {
+ Popup.IsOpen = false;
+ Button.Focus();
+ }
+ }
}
}
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/Clock.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/Clock.xaml
index 50c52b81..97aa83ba 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/Clock.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/Clock.xaml
@@ -11,7 +11,7 @@
-
-
+
+
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml
index 48f7ba96..7732cc79 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml
@@ -14,24 +14,22 @@
-
-
+
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs
index 2b0c827a..89f7f336 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs
@@ -43,6 +43,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
CultureCodeTextBlock.Text = layout.CultureCode;
CultureNameTextBlock.Text = layout.CultureName;
LayoutNameTextBlock.Text = layout.LayoutName;
+ System.Windows.Automation.AutomationProperties.SetHelpText(Button, layout.LayoutName);
}
}
}
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml
index e54cae82..d2c1b3c9 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml
@@ -16,7 +16,7 @@
-
+
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs
index 2c9ab85a..091ce98d 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs
@@ -45,7 +45,14 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
InitializeLayouts();
keyboard.LayoutChanged += Keyboard_LayoutChanged;
- Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
+ Button.Click += (o, args) =>
+ {
+ Popup.IsOpen = !Popup.IsOpen;
+ Task.Delay(200).ContinueWith(_ => this.Dispatcher.BeginInvoke((System.Action) (() =>
+ {
+ ((LayoutsStackPanel.Children[0] as ContentControl).Content as UIElement).Focus();
+ })));
+ };
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
Popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
@@ -114,5 +121,14 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
LayoutCultureCode.Text = layout.CultureCode;
Button.ToolTip = tooltip;
}
+
+ private void Popup_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ if (e.Key == System.Windows.Input.Key.Enter || e.Key == System.Windows.Input.Key.Escape)
+ {
+ Popup.IsOpen = false;
+ Button.Focus();
+ }
+ }
}
}
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/NetworkControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/NetworkControl.xaml.cs
index 04c04b7e..0c065270 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/NetworkControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/NetworkControl.xaml.cs
@@ -88,6 +88,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
{
WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name);
+ Button.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, Button.ToolTip as string);
}
WirelessNetworksStackPanel.Children.Add(button);
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml
index 62973263..957dcc88 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml
@@ -4,7 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls"
- mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40">
+ mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40" Focusable="True" IsTabStop="True">
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml.cs
index cb9045b8..a0eae5f1 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/PowerSupplyControl.xaml.cs
@@ -101,6 +101,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
Button.ToolTip = tooltip;
PowerPlug.Visibility = status.IsOnline ? Visibility.Visible : Visibility.Collapsed;
Warning.Visibility = status.BatteryChargeStatus == BatteryChargeStatus.Critical ? Visibility.Visible : Visibility.Collapsed;
+ this.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, tooltip);
}
private void RenderCharge(double charge, BatteryChargeStatus status)
diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/QuitButton.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/QuitButton.xaml
index b9ecf231..7dc1878f 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/QuitButton.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/QuitButton.xaml
@@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls"
+ x:Name="root"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40">
@@ -15,6 +16,7 @@
+ Template="{StaticResource TaskbarButton}" VerticalAlignment="Stretch"
+ AutomationProperties.Name="{Binding Path=(AutomationProperties.Name), ElementName=root}" />
diff --git a/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml b/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml
index a6398f78..2ae17373 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml
@@ -62,15 +62,15 @@
-
+
-
+
-
+
@@ -80,7 +80,7 @@
-
+
@@ -90,7 +90,7 @@
-
+
diff --git a/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml.cs
index 9efbbc72..2c038b57 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Windows/BrowserWindow.xaml.cs
@@ -8,6 +8,7 @@
using System;
using System.ComponentModel;
+using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls.Primitives;
@@ -35,12 +36,15 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
private const string CLEAR_FIND_TERM = "thisisahacktoclearthesearchresultsasitappearsthatthereisnosuchfunctionalityincef";
private readonly bool isMainWindow;
- private readonly ILogger logger;
private readonly BrowserSettings settings;
private readonly IText text;
+ private readonly ILogger logger;
+ private readonly IBrowserControl browserControl;
private WindowClosedEventHandler closed;
private WindowClosingEventHandler closing;
+ private bool browserControlGetsFocusFromTaskbar = false;
+ private IInputElement tabKeyDownFocusElement = null;
private WindowSettings WindowSettings
{
@@ -56,12 +60,12 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
public event ActionRequestedEventHandler DeveloperConsoleRequested;
public event FindRequestedEventHandler FindRequested;
public event ActionRequestedEventHandler ForwardNavigationRequested;
- public event LoseFocusRequestedEventHandler LoseFocusRequested { add { } remove { } }
public event ActionRequestedEventHandler HomeNavigationRequested;
public event ActionRequestedEventHandler ReloadRequested;
public event ActionRequestedEventHandler ZoomInRequested;
public event ActionRequestedEventHandler ZoomOutRequested;
public event ActionRequestedEventHandler ZoomResetRequested;
+ public event LoseFocusRequestedEventHandler LoseFocusRequested;
event WindowClosedEventHandler IWindow.Closed
{
@@ -78,9 +82,10 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
internal BrowserWindow(IBrowserControl browserControl, BrowserSettings settings, bool isMainWindow, IText text, ILogger logger)
{
this.isMainWindow = isMainWindow;
- this.logger = logger;
this.settings = settings;
this.text = text;
+ this.logger = logger;
+ this.browserControl = browserControl;
InitializeComponent();
InitializeBrowserWindow(browserControl);
@@ -191,7 +196,12 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
public void UpdateZoomLevel(double value)
{
- Dispatcher.Invoke(() => ZoomLevel.Text = $"{value}%");
+ Dispatcher.Invoke(() =>
+ {
+ ZoomLevel.Text = $"{value}%";
+ var zoomButtonHelpText = this.text.Get(TextKey.BrowserWindow_ZoomLevelReset).Replace("%%ZOOM%%", value.ToString("0"));
+ ZoomResetButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, zoomButtonHelpText);
+ });
}
private void BrowserWindow_Closing(object sender, CancelEventArgs e)
@@ -206,6 +216,33 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
}
}
+ private void BrowserWindow_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Tab)
+ {
+ var hasShift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
+ if (Toolbar.IsKeyboardFocusWithin && hasShift)
+ {
+ var firstActiveElementInToolbar = Toolbar.PredictFocus(FocusNavigationDirection.Right);
+ if (firstActiveElementInToolbar is System.Windows.UIElement)
+ {
+ var control = firstActiveElementInToolbar as System.Windows.UIElement;
+ if (control.IsKeyboardFocusWithin)
+ {
+ this.LoseFocusRequested?.Invoke(false);
+ e.Handled = true;
+ }
+ }
+ }
+
+ tabKeyDownFocusElement = FocusManager.GetFocusedElement(this);
+ }
+ else
+ {
+ tabKeyDownFocusElement = null;
+ }
+ }
+
private void BrowserWindow_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.F5)
@@ -222,6 +259,71 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
{
ShowFindbar();
}
+
+ if (e.Key == Key.Tab)
+ {
+ var hasCtrl = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
+ var hasShift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
+ if (BrowserControlHost.IsFocused && hasCtrl)
+ {
+ if (Findbar.Visibility == Visibility.Hidden || hasShift)
+ {
+ Toolbar.Focus();
+ }
+ else if (Toolbar.Visibility == Visibility.Hidden)
+ {
+ Findbar.Focus();
+ }
+ }
+ else if (MenuPopup.IsKeyboardFocusWithin)
+ {
+ var focusedElement = FocusManager.GetFocusedElement(this);
+ var focusedControl = focusedElement as System.Windows.Controls.Control;
+ var prevFocusedControl = tabKeyDownFocusElement as System.Windows.Controls.Control;
+ if (focusedControl != null && prevFocusedControl != null)
+ {
+ //var commonAncestor = focusedControl.FindCommonVisualAncestor(prevFocusedControl);
+ //var nextTab = GetNextTab(MenuPopup, this, true);
+ if (!hasShift && focusedControl.TabIndex < prevFocusedControl.TabIndex)
+ {
+ MenuPopup.IsOpen = false;
+ FocusBrowser();
+ }
+ else if (hasShift && focusedControl.TabIndex > prevFocusedControl.TabIndex)
+ {
+ MenuPopup.IsOpen = false;
+ MenuButton.Focus();
+ }
+ }
+ }
+ }
+
+ if (e.Key == Key.Escape && MenuPopup.IsOpen)
+ {
+ MenuPopup.IsOpen = false;
+ MenuButton.Focus();
+ }
+ }
+
+ ///
+ /// Get next tab order element. Copied from https://stackoverflow.com/questions/5756448/in-wpf-how-can-i-get-the-next-control-in-the-tab-order
+ ///
+ /// The element to get next tab order
+ /// The container element owning 'e'. Make sure this is a container of 'e'.
+ /// True if search only itself and inside of 'container'; otherwise false.
+ /// If true and next tab order element is outside of 'container', result in null.
+ /// Next tab order element or null if not found
+ public DependencyObject GetNextTab(DependencyObject e, DependencyObject container, bool goDownOnly)
+ {
+ var navigation = typeof(FrameworkElement)
+ .GetProperty("KeyboardNavigation", BindingFlags.NonPublic | BindingFlags.Static)
+ .GetValue(null);
+
+ var method = navigation
+ .GetType()
+ .GetMethod("GetNextTab", BindingFlags.NonPublic | BindingFlags.Instance);
+
+ return method.Invoke(navigation, new object[] { e, container, goDownOnly }) as DependencyObject;
}
private void BrowserWindow_Loaded(object sender, RoutedEventArgs e)
@@ -327,10 +429,11 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
ForwardButton.Click += (o, args) => ForwardNavigationRequested?.Invoke();
HomeButton.Click += (o, args) => HomeNavigationRequested?.Invoke();
Loaded += BrowserWindow_Loaded;
- MenuButton.Click += (o, args) => MenuPopup.IsOpen = !MenuPopup.IsOpen;
+ MenuButton.Click += MenuButton_Click;
MenuButton.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => MenuPopup.IsOpen = MenuPopup.IsMouseOver));
MenuPopup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
MenuPopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => MenuPopup.IsOpen = MenuPopup.IsMouseOver));
+ KeyDown += BrowserWindow_KeyDown;
KeyUp += BrowserWindow_KeyUp;
LocationChanged += (o, args) => { DownloadsPopup.IsOpen = false; MenuPopup.IsOpen = false; };
ReloadButton.Click += (o, args) => ReloadRequested?.Invoke();
@@ -345,6 +448,48 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
ZoomInButton.Click += (o, args) => ZoomInRequested?.Invoke();
ZoomOutButton.Click += (o, args) => ZoomOutRequested?.Invoke();
ZoomResetButton.Click += (o, args) => ZoomResetRequested?.Invoke();
+ BrowserControlHost.GotKeyboardFocus += BrowserControlHost_GotKeyboardFocus;
+ }
+
+ private void MenuButton_Click(object sender, RoutedEventArgs e)
+ {
+ MenuPopup.IsOpen = !MenuPopup.IsOpen;
+ ZoomInButton.Focus();
+ }
+
+ private void BrowserControlHost_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
+ {
+ var forward = !this.browserControlGetsFocusFromTaskbar;
+
+ // focus the first / last element on the page
+ var javascript = @"
+if (typeof __SEB_focusElement === 'undefined') {
+ __SEB_focusElement = function (forward) {
+ var items = [].map
+ .call(document.body.querySelectorAll(['input', 'select', 'a[href]', 'textarea', 'button', '[tabindex]']), function(el, i) { return { el, i } })
+ .filter(function(e) { return e.el.tabIndex >= 0 && !e.el.disabled && e.el.offsetParent; })
+ .sort(function(a,b) { return a.el.tabIndex === b.el.tabIndex ? a.i - b.i : (a.el.tabIndex || 9E9) - (b.el.tabIndex || 9E9); })
+ var item = items[forward ? 1 : items.length - 1];
+ if (item && item.focus && typeof item.focus !== 'function')
+ throw ('item.focus is not a function, ' + typeof item.focus)
+ setTimeout(function () { item && item.focus && item.focus(); }, 20);
+ }
+}";
+ this.browserControl.ExecuteJavascript(javascript, result =>
+ {
+ if (!result.Success)
+ {
+ logger.Error($"Javascript error {result.Message}!");
+ }
+ });
+
+ this.browserControl.ExecuteJavascript("__SEB_focusElement(" + forward.ToString().ToLower() + ")", result =>
+ {
+ if (!result.Success)
+ {
+ logger.Error($"Javascript error {result.Message}!");
+ }
+ });
}
private void ApplySettings()
@@ -457,29 +602,65 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
private void LoadText()
{
DeveloperConsoleText.Text = text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem);
+ DeveloperConsoleButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem));
FindCaseSensitiveCheckBox.Content = text.Get(TextKey.BrowserWindow_FindCaseSensitive);
FindMenuText.Text = text.Get(TextKey.BrowserWindow_FindMenuItem);
+ FindMenuButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_FindMenuItem));
ZoomText.Text = text.Get(TextKey.BrowserWindow_ZoomMenuItem);
+ ZoomInButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_ZoomMenuPlus));
+ ZoomOutButton.SetValue(System.Windows.Automation.AutomationProperties.HelpTextProperty, text.Get(TextKey.BrowserWindow_ZoomMenuMinus));
+ ReloadButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_ReloadButton));
+ BackwardButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_BackwardButton));
+ ForwardButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_ForwardButton));
+ DownloadsButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_DownloadsButton));
+ HomeButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_HomeButton));
+ MenuButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_MenuButton));
+ UrlTextBox.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, text.Get(TextKey.BrowserWindow_UrlTextBox));
}
public void FocusToolbar(bool forward)
{
- throw new NotImplementedException();
+ this.Dispatcher.BeginInvoke((Action) (async () =>
+ {
+ this.Activate();
+ await Task.Delay(50);
+
+ // focus all elements in the toolbar, such that the last element that is enabled gets focus
+ var buttons = new System.Windows.Controls.Control[] { ForwardButton, BackwardButton, ReloadButton, UrlTextBox, MenuButton, };
+ for (var i = forward ? 0 : buttons.Length - 1; i >= 0 && i < buttons.Length; i += forward ? 1 : -1)
+ {
+ if (buttons[i].IsEnabled && buttons[i].Visibility == Visibility.Visible)
+ {
+ buttons[i].Focus();
+ break;
+ }
+ }
+ }));
}
public void FocusBrowser()
{
- throw new NotImplementedException();
- }
+ this.Dispatcher.BeginInvoke((Action) (async () =>
+ {
+ this.FocusToolbar(false);
+ await Task.Delay(100);
- public void Debug()
- {
- throw new NotImplementedException();
+ this.browserControlGetsFocusFromTaskbar = true;
+
+ var focusedElement = FocusManager.GetFocusedElement(this) as UIElement;
+ focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
+
+ await Task.Delay(150);
+ this.browserControlGetsFocusFromTaskbar = false;
+ }));
}
public void FocusAddressBar()
{
- this.UrlTextBox.Focus();
+ this.Dispatcher.BeginInvoke((Action) (async () =>
+ {
+ this.UrlTextBox.Focus();
+ }));
}
}
}
diff --git a/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml b/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml
index 2ce32ed0..df16cf87 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml
+++ b/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar"
xmlns:s="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d" Title="Taskbar" Background="{DynamicResource BackgroundBrush}" Height="60" FontSize="16" Width="750" WindowStyle="None"
+ KeyDown="Window_KeyDown" KeyUp="Window_KeyUp"
Topmost="True" ResizeMode="NoResize" Icon="../Images/SafeExamBrowser.ico">
diff --git a/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml.cs
index beeaff73..24040923 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Windows/Taskbar.xaml.cs
@@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
using System.ComponentModel;
using System.Windows;
using SafeExamBrowser.Browser.Contracts.Events;
@@ -19,8 +20,10 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
{
internal partial class Taskbar : Window, ITaskbar
{
- private readonly ILogger logger;
private bool allowClose;
+ private readonly ILogger logger;
+ private bool isQuitButtonFocusedAtKeyDown;
+ private bool isFirstChildFocusedAtKeyDown;
public bool ShowClock
{
@@ -32,7 +35,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
set { Dispatcher.Invoke(() => QuitButton.Visibility = value ? Visibility.Visible : Visibility.Collapsed); }
}
- public event LoseFocusRequestedEventHandler LoseFocusRequested { add { } remove { } }
+ public event LoseFocusRequestedEventHandler LoseFocusRequested;
public event QuitButtonClickedEventHandler QuitButtonClicked;
internal Taskbar(ILogger logger)
@@ -81,16 +84,19 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
public void Focus(bool fromTop)
{
- Activate();
+ Dispatcher.BeginInvoke((Action) (() =>
+ {
+ Activate();
- if (fromTop)
- {
- ApplicationStackPanel.Children[0].Focus();
- }
- else
- {
- QuitButton.Focus();
- }
+ if (fromTop)
+ {
+ ApplicationStackPanel.Children[0].Focus();
+ }
+ else
+ {
+ QuitButton.Focus();
+ }
+ }));
}
public int GetAbsoluteHeight()
@@ -143,7 +149,9 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
{
Dispatcher.Invoke(() =>
{
- QuitButton.ToolTip = text.Get(TextKey.Shell_QuitButton);
+ var txt = text.Get(TextKey.Shell_QuitButton);
+ QuitButton.ToolTip = txt;
+ QuitButton.SetValue(System.Windows.Automation.AutomationProperties.NameProperty, txt);
});
}
@@ -185,5 +193,82 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
e.Cancel = true;
}
}
+
+ private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ this.isQuitButtonFocusedAtKeyDown = this.QuitButton.IsKeyboardFocusWithin;
+ this.isFirstChildFocusedAtKeyDown = this.ApplicationStackPanel.Children[0].IsKeyboardFocusWithin;
+ }
+
+ private void Window_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ if (e.Key == System.Windows.Input.Key.Tab)
+ {
+ var shift = System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.LeftShift);
+ if (!shift && this.ApplicationStackPanel.Children[0].IsKeyboardFocusWithin && this.isQuitButtonFocusedAtKeyDown)
+ {
+ this.LoseFocusRequested?.Invoke(true);
+ e.Handled = true;
+ }
+ else if (shift && this.QuitButton.IsKeyboardFocusWithin && this.isFirstChildFocusedAtKeyDown)
+ {
+ this.LoseFocusRequested?.Invoke(false);
+ e.Handled = true;
+ }
+ }
+
+ this.isQuitButtonFocusedAtKeyDown = false;
+ this.isFirstChildFocusedAtKeyDown = false;
+ }
+
+ void ITaskbar.Focus(bool forward)
+ {
+ this.Dispatcher.BeginInvoke((Action) (() =>
+ {
+ base.Activate();
+ if (forward)
+ {
+ this.SetFocusWithin(this.ApplicationStackPanel.Children[0]);
+ }
+ else
+ {
+ this.QuitButton.Focus();
+ }
+ }));
+ }
+
+ private bool SetFocusWithin(UIElement uIElement)
+ {
+ if (uIElement.Focusable)
+ {
+ uIElement.Focus();
+ return true;
+ }
+
+ if (uIElement is System.Windows.Controls.Panel)
+ {
+ var panel = uIElement as System.Windows.Controls.Panel;
+ for (var i = 0; i < panel.Children.Count; i++)
+ {
+ if (this.SetFocusWithin(panel.Children[i]))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ else if (uIElement is System.Windows.Controls.ContentControl)
+ {
+ var control = uIElement as System.Windows.Controls.ContentControl;
+ var content = control.Content as UIElement;
+ if (content != null)
+ {
+ return this.SetFocusWithin(content);
+ }
+ }
+
+ return false;
+ }
}
}