none
[UWP] WebView и KeyDown

Ответы

  • Что-то типа такого?

    //MyWebView.AllowedScriptNotifyUris = WebView.AnyScriptNotifyUri; (до Windows 8.1)
    await MyWebView.InvokeScriptAsync("eval", 
    new[] { "document.onkeydown = function (e) { window.external.notify('Hello, UWP World!'); }" }
    );
    
    //и обработчик события
    
    private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
    {
        string parameter = e.Value;
    }
    Добавлено: для получения кода нажатой клавиши в onkeydown можно использовать e.keyCode / e.which



    • Изменено VadimTagil 16 января 2018 г. 11:42 поправка
    • Помечено в качестве ответа Liliya Muray 16 января 2018 г. 12:32
    15 января 2018 г. 19:02
  • eval по идее то же самое делает, что и execScript. Если в том же коде eval поставить, сработает? 

    • Помечено в качестве ответа Liliya Muray 16 января 2018 г. 12:31
    16 января 2018 г. 9:29

Все ответы

  • Здравствуйте,

    Может получится как описали в ответе здесь: How can I get keyboard input when WebView visible in C++/XAML/UWP App?


    Если Вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение" Мнения, высказанные здесь, являются отражение моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.

    12 января 2018 г. 14:53
    Модератор
  • Может получится как описали в ответе здесь: How can I get keyboard input when WebView visible in C++/XAML/UWP App?


    В этом решении предлагается сбрасывать фокус с WebView, а для меня это не вариант, так как в WebView идет ввод информации. Хотелось добавить вспомогательные функции по сочетанию клавиш.

    Пока встречала два варианта: AddHandler и InvokeScriptAsync. Но пока не могу понять как они работают. Думала найдется кто-то кто ткнет носом в готовый рабочий код для C# UWP.

    12 января 2018 г. 16:15
  • Добрый день,

    Можете использовать AddHandler следующим образом
      public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                this.AddHandler(UIElement.KeyDownEvent, new KeyEventHandler(KeyDownEventHandler) , true);
            }
    
            private void KeyDownEventHandler(object sender, KeyRoutedEventArgs e)
            {
              
            }
        }


    Make the community better together



    • Изменено Azat Tazayan 15 января 2018 г. 10:43
    15 января 2018 г. 10:41
  • Добрый день,

    Можете использовать AddHandler следующим образом
      public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                this.AddHandler(UIElement.KeyDownEvent, new KeyEventHandler(KeyDownEventHandler) , true);
            }
    
            private void KeyDownEventHandler(object sender, KeyRoutedEventArgs e)
            {
              
            }
        }

    Спасибо за подсказку про "AddHandler", но для WebView это не прокатывает, если фокус на нем. Значит надо копать будет в сторону скриптов.
    15 января 2018 г. 12:47
  • Что-то типа такого?

    //MyWebView.AllowedScriptNotifyUris = WebView.AnyScriptNotifyUri; (до Windows 8.1)
    await MyWebView.InvokeScriptAsync("eval", 
    new[] { "document.onkeydown = function (e) { window.external.notify('Hello, UWP World!'); }" }
    );
    
    //и обработчик события
    
    private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
    {
        string parameter = e.Value;
    }
    Добавлено: для получения кода нажатой клавиши в onkeydown можно использовать e.keyCode / e.which



    • Изменено VadimTagil 16 января 2018 г. 11:42 поправка
    • Помечено в качестве ответа Liliya Muray 16 января 2018 г. 12:32
    15 января 2018 г. 19:02
  • Что-то типа такого?

    MyWebView.AllowedScriptNotifyUris = WebView.AnyScriptNotifyUri;
    MyWebView.InvokeScript("execScript", 
    new[] { "document.onkeydown = function (e) { window.external.notify('Hello, UWP World!'); }" }
    );
    
    //и обработчик события
    
    private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
    {
        string parameter = e.Value;
    }
    Добавлено: для получения кода нажатой клавиши в onkeydown можно использовать e.keyCode / e.which


    Да, что-то типа такого))) Но обе строчки вызывают ошибку "System.NotImplementedException: "The method or operation is not implemented."".
    16 января 2018 г. 8:05
  • Да, это устарело. Нужно вместо InvokeScript использовать InvokeScriptAsync.

    И вместо AnyScriptNotifyURL - включить URL в параметр манифеста ApplicationContentUriRules 

    16 января 2018 г. 8:26
  • Да, это устарело. Нужно вместо InvokeScript использовать InvokeScriptAsync.

    И вместо AnyScriptNotifyURL - включить URL в параметр манифеста ApplicationContentUriRules 

    Использую InvokeScriptAsync, для возврата значения ("eval") работает даже без ApplicationContentUriRules.

    А вот при параметре "execScript" валится...

    16 января 2018 г. 8:42
  • eval по идее то же самое делает, что и execScript. Если в том же коде eval поставить, сработает? 

    • Помечено в качестве ответа Liliya Muray 16 января 2018 г. 12:31
    16 января 2018 г. 9:29
  • eval по идее то же самое делает, что и execScript. Если в том же коде eval поставить, сработает? 

    Срабатывает для добавленного в ApplicationContentUriRules. А как нибудь можно получить AnyScriptNotifyURL?
    16 января 2018 г. 10:15
  • Похоже никак. https://msdn.microsoft.com/ru-ru/library/windows/apps/windows.ui.xaml.controls.webview.anyscriptnotifyuri.aspx?f=255&MSPPError=-2147217396

    Прекращение клиентской поддержки

    Windows 8.1

    Теперь можно только для URL, внесенных в список. Причем внести в список запись типа *.* нельзя. Оно и понятно, такие схемы слишком небезопасны для UWP.

    Так что легкого пути нет, если нужно заставить это работать на любых сайтах.

    Добавлено: возможно есть какой-то обходной путь, например через CoreWindow.KeyDown

    • Изменено VadimTagil 16 января 2018 г. 12:00
    16 января 2018 г. 11:40
  • Похоже никак. https://msdn.microsoft.com/ru-ru/library/windows/apps/windows.ui.xaml.controls.webview.anyscriptnotifyuri.aspx?f=255&MSPPError=-2147217396

    Прекращение клиентской поддержки

    Windows 8.1

    Теперь можно только для URL, внесенных в список. Причем внести в список запись типа *.* нельзя. Оно и понятно, такие схемы слишком небезопасны для UWP.

    Так что легкого пути нет, если нужно заставить это работать на любых сайтах.

    Добавлено: возможно есть какой-то обходной путь, например через CoreWindow.KeyDown

    Да, придется попотеть))) Фильтр *.* работает, но сертификацию не проходит)))

    Манифест приложения
    • Обнаружена ошибка: При тестировании манифеста приложения обнаружены следующие ошибки:
      • Приложению не разрешено объявлять URI со знаками подстановки в домене: "http://*.*"
      • Приложению не разрешено объявлять URI со знаками подстановки в домене: "https://*.*"

    16 января 2018 г. 12:31
  •  "Hажатое сочетание клавиш" - это когда две клавиши, например m и n, нажимаются вместе?

    А если просто использовать обработчик KeyDown?

     Попробовал запустить следующий код. С WebView раньше не работал. Событие KeyDown на нем у меня вообще почему-то не возникает. 

    А вот с TextBox этот код работает.

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
            <Grid.RowDefinitions>
                <RowDefinition Height="35*"/>
                <RowDefinition Height="37*"/>
            </Grid.RowDefinitions>
            <TextBox Name="tb1" HorizontalAlignment="Left" Margin="74,76,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" KeyDown="TextBox_KeyDown"/>
    
            <WebView x:Name="webView" Grid.Row="1" KeyDown="WebView_KeyDown1" Source="https://www.microsoft.com" Margin="74,-78,-74,78" Grid.RowSpan="2" />
        </Grid>
    

    namespace DoubleKeyDown
    {
      
        public sealed partial class MainPage : Page
        {    int i = 0;
            char[] chararray1 = new char[2];
            public MainPage()
            {
                this.InitializeComponent();
    
            }
    
            private void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
            {
    
                if (i > 1) { i = 0; }
                chararray1[i] = (char)(e.Key); i++;
                string str = new string(chararray1);
    
                if (str == "MN" || str == "NM")
                {
                    // нажата сочетание mn 
                }
            }
    
            private void WebView_KeyDown1(object sender, KeyRoutedEventArgs e)
            {
                // событие почему-то не наступает
                if (i > 1) { i = 0; }
                chararray1[i] = (char)(e.Key);
                i++;
                string str = new string(chararray1);
                if(str== "MN" || str == "NM") {
                    // нажата сочетание mn
                }
    
            }
     
        }
    }


    Фоновое изображение

    21 ч. 39 мин. назад
  • Событие не наступает скорее всего потому что бразуер (а WebView это просто бразуер в обертке компонента) его обрабатывает.

    Скорее всего та же самая проблема будет и со скриптом в браузере так как если кто то обработает событие до того как оно доползет до документа, то на документе его тоже никогда не будет. 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    20 ч. 11 мин. назад
  • Да, хоть и редко кто обрабатывает события на уровне отдельных HTML-элементов, а для document могут вместе уживаться несколько обработчиков (при использовании addEventListener вместо "=" ), в целом метод с JS-обработчиками хрупкий. Если где-то вызывается preventDefault, все сломается.

    Наверное, должен быть какой-то другой метод, с использованием глобальных событий, вызываемых до передачи события конкретным элементам. Через CoreWindow.KeyDown или CoreWindow.Dispatcher.AcceleratorKeyActivated. В крайнем случае, через периодический опрос CoreWindow.GetKeyState, если не смущает постоянная загрузка процессора.

    14 ч. 7 мин. назад
  • Приложение прошло сертификацию... Всем спасибо за помощь!

    Проблема в том, что WebView не отдает обработку клавиатуры. Вот написано в документации:

    Как указано в таблице событий, WebView не поддерживает большинство событий пользовательского ввода, наследуемых от UIElement, таких как KeyDown, KeyUpи PointerPressed. Распространенное решение этой проблемы — использование WebView.InvokeScript (InvokeScriptAsync, начиная с Windows 8.1) с eval для использования обработчиков событий HTML, а также использование window.external.notify из обработчика событий HTML для уведомления приложения с помощью WebView.ScriptNotify.

    Плюс еще запретили скрипты, если доменное имя и протокол не прописаны в манифесте. Использовать "*" можно на доменах с 3 уровня ("https://*.uwpdev.ru") и так далее. Кол-во доменов-протоколов-фильтров ограничен сотней.

    Для опытов (на этапе разработки) можно использовать фильтры "http://*.*" и "https://*.*", но сертификацию с ними не пройти!

    Еще раз спасибо за помощь!

    11 ч. 26 мин. назад
  •  "Hажатое сочетание клавиш" - это когда две клавиши, например m и n, нажимаются вместе?


    Сочетание клавиш - это так называемые горячие клавиши. Типа "Ctrl+P" - вызывает печать.
    11 ч. 23 мин. назад
  •  Полагал, что если событие есть в функционале элемента, отображается в окне свойств, и компилятор на него не ругается , то оно должно как то работать.

    Оказывается что нет. Для WebViev одни события GotFocus работают, а клавиатурные не поддерживаются.


    Фоновое изображение

    10 ч. 55 мин. назад
  • "если событие есть в функционале элемента, отображается в окне свойств, и компилятор на него не ругается , то оно должно как то работать"

    Не ругается, потому что WebView унаследован от UIElement, у которого есть это событие. По правилам ООП, класс-наследник не может "удалить" элемент, определенный в базовом классе, так и получается событие, которое существует, но ничего не делает.

    10 ч. 16 мин. назад
  •  "так и получается событие, которое существует, но ничего не делает."

    Тогда, по хорошему, нужно удалить из меню событий для WebView, событие KeyDown и другой неподдерживаемый функционал.

     Получается как в ресторане. Пришел, заказал по электронному меню стейк. Ждешь пока кто нибудь не скажет  что стейки не поддерживаются.


    Фоновое изображение

    8 ч. 46 мин. назад