如何通过MVVM在WPF WebBrowser控件上使用Javascript

Kye*_*ica 19 javascript c# wpf webbrowser-control

我在WPF4上使用MVVM模式,虽然我对两者都是新手.我正在寻找一个很好的解决方案来使用WebBrowser控件,它可以接收Javascript命令并与ViewModel通信.它需要以下内容:

  1. 能够从Javascript表单收集值,并将它们返回到ViewModel
  2. 使用Javascript之前确定ReadyState
  3. 运行Javascript命令(设置表单值,使用逻辑步骤的表单值,提交表单),这些命令发生在多个页面加载中

正在处理的网站不受我的控制,无法编辑或更新.它大量使用ActiveX并且不接受非IE浏览器(Awesomium不起作用),因此标准的WPF WebBrowser控件可能是唯一的选择.

此问题提供了将浏览器控件的源与附加属性绑定的解决方案.我认为这可以适用于使用导航方法发送javascript,但我不确定如何将值返回到Viewmodel.这是我需要克服的主要障碍.

重编辑 - 问题收到非常低的观点,没有答案,完全重写

The*_*ing 10

好吧,如果您正在与网站开发人员合作为您的应用程序创建解决方案,那么您将使用ObjectForScriptingJavaScript和应用程序之间的通信.有一个很好的文章在这里,和这可能是有益的另外一个问题在这里.

但是,据我了解您的问题,该网站是一个任意第三方网站,与您的应用程序没有任何关联,您想要自动填写一些表单值并在您的代码中提交表单.

为此,您可以处理LoadCompletedWebBrowser 的事件.加载的文档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();
                }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,NavigationEventArgs它没有提供访问HTML文档或请求数据的方法.它确实包含一个WebRequest属性,但尚未实现,并且始终为null.在我的示例中,我假设了一个自定义EventToCommandWithSender类,它在事件触发时提供发件人以及事件ARG,但这取决于您自己的实现以获取对发件人的访问权限.


Kye*_*ica 7

我不知道为什么以前从未发生这种情况,但解决方案似乎很简单.

不要<WebBrowser在视图上使用>控件,而是使用a <ContentControl>并将其内容绑定到ViewModel中的WebBrowser属性.在ViewModel的构造函数中创建WebBrowser,然后您可以将浏览器的导航事件(或documentloaded)注册到ViewModel中的事件.

从ViewModel完全控制浏览器!您甚至可以捕获用户事件,因为他们在浏览页面时执行的任何操作都将在ViewModel的导航事件中捕获.