winform窗体中使用WebBrowser嵌入网页

@bruce  July 14, 2020

WebBrowser可以使用WebBrowser控件向Windows窗体客户端应用程序添加现有的动态的Web应用程序。

使用WebBrowser控件,可以通过ObjectForScripting和Document属性在客户端应用程序代码和网页脚本代码之间实现双向通信。
此外,可以对WebBrowser控件进行配置,使Web控件可以与应用程序窗体上的其他控件进行无缝整合,从而隐藏其HTML实现。
若要使控件无缝整合,请对所显示页的格式进行设置,使其背景颜色和视觉样式与窗体的其余部分匹配,然后使用AllowWebBrowserDrop、 IsWebBrowserContextMenuEnabled和WebBrowserShortcutsEnabled属性禁用标准浏览器功能。

webBrowser1.AllowWebBrowserDrop = false;//将 WebBrowser 控件的 AllowWebBrowserDrop 属性设置为 false,以防止 WebBrowser 控件打开拖放到其上的文件。
webBrowser1.IsWebBrowserContextMenuEnabled = false;//将该控件的 IsWebBrowserContextMenuEnabled 属性设置为 false,以防止 WebBrowser 控件在用户右击它时显示其快捷菜单.
webBrowser1.WebBrowserShortcutsEnabled = false;//将该控件的 WebBrowserShortcutsEnabled 属性设置为 false,以防止 WebBrowser 控件响应快捷键。
webBrowser1.ScriptErrorsSuppressed=true;//将该控件的 ScriptErrorsSuppressed 属性设置为 true,以防止 WebBrowser 控件显示脚本代码问题的错误信息。

WebBrowser不单单只做一个浏览器的功能吧,既然是winform程序,那么就牵涉到网页的程序(主要是javascript)和winform本身的程序怎样交互呢?一些Javascript无法实现的功能,可以通过javascript调用Winform里的方法去完成。

1.在窗体的构造函数或者Load事件处理程序中设置ObjectForScripting属性:下面代码将窗体类自身用于脚本对象。
(组件对象模型(COM)必须能够访问脚本对象,若要使窗体对 COM 可见,请将 ComVisibleAttribute 属性添加到窗体类中)

webBrowser1.ObjectForScripting = this;

在窗体类自身设置Attribute

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{}

2.在应用程序中实现脚本代码将要调用的winform的公共属性和方法。

public string InvokeFormMethod(string message)
{
   MessageBox.Show(message,"Client Code")
   return "Charles2008"
}

3.在脚本代码中使用window.external对象访问指定对象的公共属性和方法。

<input type="button" text="调用winform中的方法" value="测试调用winform的方法" onclick="alert(window.external.InvokeFormMethod())">

4.在脚本文件中添加JavaScript函数(winform程序将要调用的).

<script>
function msgalert(msg)
{
   alert(msg);
}
</script>

5.使用WebBrowser的Document 属性从客户端应用程序代码访问脚本代码。

this.webBrowser1.Document.InvokeScript("msgalert", new string[] { "Called Javascript code" });

下面是一个完整的实例:

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class Main : Form
{
    public Main()
    {
        InitializeComponent();
    }

    private void button4_Click(object sender, EventArgs e)
    {
        this.webBrowser1.Navigate(this.textBox1.Text);
        this.webBrowser1.ObjectForScripting = this;
    }

    #region JavaScript中调用的方法
    public string InvokeFormMethod(string message)
    {
        MessageBox.Show(message);
        return "Somthing";
    }
    #endregion

    #region 调用Javascript方法
    private void button6_Click(object sender, EventArgs e)
    {            
        this.webBrowser1.Document.InvokeScript("msgalert", new string[] { "Called from client code" });
    }
    #endregion
}

脚本错误的解决方案

当IE浏览器遇到脚本错误时,在浏览器左下角会出现一个黄色图标,点击可以查看脚本错误的详细信息,并不会有弹出的错误信息框。我们在用webBrowser编写的程序打开网页,遇到脚本有问题是,会弹出一个错误提示框,需要确认后才能够进行执行, 在winform程序中这会影响用户的使用体验。那么,在使用WebBrowser打开网页遇到脚本错误时如何处理才能让程序无干扰的自动运行呢?

WebBrowser给我们提供了一个属性:ScriptErrorsSuppressed 。当不想再遇到脚本错误时弹出错误提示框,可以将该值设为TRUE。

WebBrowser.ScriptErrorsSuppressed = true;

ScriptErrorsSuppressed 属性的具体的用法如下:

将此属性设置为 false 可调试显示在 WebBrowser 控件中的网页。如果要使用该控件向应用程序添加基于 Web 的控件和脚本代码,则此属性十分有用。如果将该控件用作泛型浏览器,则此属性用处不大。完成应用程序的调试后,将此属性设置为 true 以取消显示脚本错误。

注意:当 ScriptErrorsSuppressed 设置为 true 时,WebBrowser 控件将隐藏其源自基础 ActiveX 控件的所有对话框,而不仅仅是脚本错误。有时,在显示某些对话框(例如,用于浏览器安全设置和用户登录的对话框)时,可能需要取消显示脚本错误。在这种情况下,应将 ScriptErrorsSuppressed 设置为 false,并在 HtmlWindow.Error 事件的处理程序中取消显示脚本错误。

下面的代码演示如何在不取消显示其他对话框的情况下取消显示脚本错误。在此示例中,将 ScriptErrorsSuppressed 属性设置为 false 以确保显示对话框。HtmlWindow.Error 事件的处理程序取消显示该错误。只有在文档已完成加载时才能访问此事件,因此该处理程序被附加到 DocumentCompleted 事件处理程序中。

// 仅隐藏脚本错误,其他错误照样提示
private void SuppressScriptErrorsOnly(WebBrowser browser)
{
    // 确信 ScriptErrorsSuppressed 设为 false.
    browser.ScriptErrorsSuppressed = false;

    // 处理 DocumentCompleted 事件以访问 Document 对象.    
    browser.DocumentCompleted +=  
        new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);    

    private void browser_DocumentCompleted(object sender,
    WebBrowserDocumentCompletedEventArgs e)
    {
        ((WebBrowser)sender).Document.Window.Error +=
            new HtmlElementErrorEventHandler(Window_Error);
    }

    private void Window_Error(object sender, HtmlElementErrorEventArgs e)
    {
        // 忽略该错误并抑制错误对话框
        e.Handled = true;
    }
}

获取Post内容

string postData = "value1=" + 1 + "&value2=" + 2 + "&value3=" + 3;
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
byte[] bytes = encoding.GetBytes(postData);
string url = "http://www.domain.com/addSomething";
webBrowser1.Navigate(url, string.Empty, bytes, "Content-Type: application/x-www-form-urlencoded");

补充

WebBrower修改使用的浏览器内核,只需在html文件的头部添加如下代码即可

<meta http-equiv="X-UA-Compatible" content="IE=edge" >

添加新评论