在MessageDialog关闭后关注WebView

ror*_*yok 6 c# xaml webview windows-8 windows-store-apps

我的Windows Store应用程序中有一个contentEditable基于编辑器的编辑器WebView.某些键盘快捷键和按钮可能会导致MessageDialog打开.解除此对话框后,编辑器不再具有焦点.我已经尝试过以我所知道的方式设置焦点,但它不起作用.这是一个示例应用程序.

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>
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,WebView重点是,而不是内容中的HTML内容

更新:

更新了我的示例,从下面的答案添加Bryan的代码,但它仍然无法正常工作.

注意 MessageDialog被关闭后,如果我按Tab两次,编辑器将再次激活.

更新2:

使用触摸屏导航时,下面的布莱恩答案确实有效.但是,使用鼠标和键盘时,contentEditable元素不会聚焦.我为此寻找了一个解决方案,它允许在使用触摸屏或鼠标/键盘组合时对项目进行聚焦

Bry*_*ump 4

如果您在 C# 中设置焦点状态,则正确的参数始终是 FocusState.Programmatic。其他值的目的是读取当前焦点值。

听起来您正在尝试将控件集中在 web 视图中而不是实际的 web 视图中。C#/XAML 方面不会知道 Web 视图中的内容。为此,您必须调用 javascript,它会了解控件。

这是有关您的场景的 MSDN 链接。WebView.Focus方法

编辑:根据文章,WebView 必须首先获得焦点,然后调用 javascript。

    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);
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是我的 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>
Run Code Online (Sandbox Code Playgroud)