Как использовать Javascript в элементе управления WPF WebBrowser через MVVM - PullRequest
19 голосов
/ 24 августа 2011

Я использую шаблон MVVM на WPF4, хотя я новичок в обоих. Я ищу хорошее решение для использования элемента управления WebBrowser, который может получать команды Javascript и общаться с ViewModel. Для этого необходимо следующее:

  1. Возможность собирать значения из форм Javascript и возвращать их в ViewModel
  2. Используйте Javascript для определения ReadyState до
  3. Выполнение команд Javascript (установка значений формы, использование значений формы для логических шагов, отправка формы), которые происходят при нескольких загрузках страницы

Сайт, над которым я работаю, не подлежит редактированию или обновлению. Он интенсивно использует ActiveX и не будет принимать браузеры, отличные от IE (Awesomium не будет работать), поэтому стандартный элемент управления WPF WebBrowser, вероятно, является единственным вариантом.

Этот вопрос предоставляет решение для связывания источника элемента управления браузера с прикрепленным свойством. Я думаю, что это может быть адаптировано для использования метода навигации для отправки JavaScript, хотя я не уверен, как значения могут быть возвращены в Viewmodel. Это главное препятствие, которое мне нужно преодолеть.

Тяжелое редактирование - Вопрос получен с очень низким числом просмотров и без ответов, полностью перефразирован

Ответы [ 2 ]

10 голосов
/ 28 августа 2011

Ну, если бы вы работали с разработчиками сайта над созданием решения для вашего приложения, то вы бы использовали ObjectForScripting для связи между JavaScript и приложением. Есть хорошая статья здесь и еще один вопрос, который может быть полезен здесь .

Однако, как я понимаю ваш вопрос, сайт является произвольным сторонним сайтом, не связанным с вашим приложением, и вы хотите автоматически заполнить некоторые значения формы и отправить форму в своем коде.

Для этого вы можете обработать событие LoadCompleted WebBrowser. Вызывается, когда загруженный документ readyState изменяется на завершенный. Поэтому вы можете использовать это событие как ловушку для установки / чтения значений формы документа. Обратите внимание, что вам нужно будет добавить ссылку на Microsoft mshtml в проекте.

Ниже приведена команда в стиле MVVM (PRISM), которая позволяет событию привязываться непосредственно к ViewModel с использованием поведений. Это эквивалентно регистрации обработчика события в коде позади.

public ICommand LoadCompleted
{
    get
    {
        return new EventToCommandWithSender<NavigationEventArgs>(
            (s,e) => { 

               WebBrowser browser = (WebBrowser) sender;
               // false if nested frame
               if (e.IsNavigationInitiator)
               {
                   mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)browser.Document;
                   // always completed
                   var readyState = doc.readyState;
                   // populate form
                   var name = doc.body.document.getElementById("username");
                   name.value = "@TheCodeKing";
                   // submit form
                   var submit = doc.body.document.getElementById("submit");
                   submit.Click();
                }
        });
    }
}

К сожалению, NavigationEventArgs не предоставляет способа доступа к документу HTML или запроса данных. Он содержит свойство WebRequest, но оно не было реализовано и всегда будет нулевым. В моем примере я использовал пользовательский класс EventToCommandWithSender, который предоставляет отправителю, а также ARG события при возникновении события, но только ваша собственная реализация может получить доступ к отправителю.

7 голосов
/ 02 сентября 2011

Я не знаю, почему это никогда не случалось со мной раньше, но решение кажется таким простым.

Вместо того, чтобы иметь <WebBrowser> элемент управления для вида, используйте <ContentControl> и связывайте егосодержимое в свойство WebBrowser в вашей модели представления.Создайте WebBrowser в конструкторе вашей ViewModel, а затем вы можете зарегистрировать событие навигации браузера (или загруженный документ) для события в вашей ViewModel.

Полный контроль браузера из ViewModel!Вы даже можете захватывать пользовательские события, поскольку все, что они делают для навигации по странице, будет записано в навигационном событии ViewModel.

...