I've got a contentEditable
based editor within a WebView
in my Windows Store app. Certain keyboard shortcuts and buttons can cause a MessageDialog
to open. When this dialog is dismissed, the editor no longer has focus. I've tried setting focus every way I know, and it won't work. Here's a sample app.
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<WebView x:Name="Editor" Margin="200"></WebView>
</Grid>
<Page.BottomAppBar>
<CommandBar x:Name="CommandBar_Editor" Visibility="Visible">
<AppBarButton Label="Debug" Icon="Setting">
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="show dialog, then focus" Click="MenuFlyoutItem_Click_1"/>
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
</Page>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Editor.NavigateToString("<script type='text/javascript'>function focus_please(){ document.getElementById('editor').focus(); }</script><div id='editor' contentEditable='true'>It was the best of times, it was the worst of times</div>");
}
private async void MenuFlyoutItem_Click_1(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("this should set focus to editor on close", "test");
UICommand okCommand = new UICommand("OK");
dialog.Commands.Add(okCommand);
IUICommand response = await dialog.ShowAsync();
if (response == okCommand)
{
Editor.Focus(FocusState.Programmatic);
// I've also tried:
// FocusState.Keyboard
// FocusState.Pointer
// FocusState.Unfocused
// this calls JS within the HTML to focus the contentEditable div
await Editor.InvokeScriptAsync("focus_please", null);
}
}
}
It seems to me that the WebView
is focussed, but not the HTML content within
Updated my example to add in Bryan's code from the answer below, but it's still not working.
Note After the MessageDialog is dismissed, if I press Tab
twice the editor becomes active again.
Bryan's answer below does work when using the touch screen to navigate. However when using mouse and keyboard, the contentEditable
element does not focus. I've put a bounty on this looking for a solution which allows the item to be focussed either when using the touch screen or the mouse / keyboard combo
If you set focus state in C# the correct parameter is always FocusState.Programmatic. The other values are there for the purpose of reading the current focus value.
Sounds like you are trying to focus the control within the webview instead of the actual webview. The C#/XAML side of things will not know about the content within the webview. For that you will have to invoke javascript which will know about the controls.
Here is a link to MSDN on your scenerio. WebView.Focus method
Edit: According to the article, the WebView must get focus first, then the javascript invoked.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string html = "<html><head><script type='text/javascript'>function focusContent()" +
" {if(window.location.hash != '#TaleofTwoCities'){ window.location.hash = '#TaleofTwoCities';}};" +
"</script></head><body><div id='TaleofTwoCities' contentEditable='true'>It was the best of times, it was the worst of times</div></body></html>";
Editor.NavigateToString(html);
}
private async void MenuFlyoutItem_Click_1(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("this should set focus to editor on close", "test");
UICommand okCommand = new UICommand("OK");
dialog.Commands.Add(okCommand);
IUICommand response = await dialog.ShowAsync();
if (response == okCommand)
{
await Window.Current.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Editor.Focus(FocusState.Programmatic);
});
await Window.Current.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Editor.InvokeScript("focusContent", null);
});
}
}
Here's my XAML
<Page x:Class="StackOverflow.WebViewFocus"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:StackOverflow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Center"><WebView Width="300"
x:Name="Editor"
Height="300"></WebView>
<Button Click="MenuFlyoutItem_Click_1">focus</Button>
</StackPanel>
</Grid>
<Page.BottomAppBar>
<CommandBar x:Name="CommandBar_Editor"
Visibility="Visible">
<AppBarButton Label="Debug"
Icon="Setting">
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="show dialog, then focus"
Click="MenuFlyoutItem_Click_1" />
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
</Page>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With