How to: Implement Two-Way Communication Between DHTML Code and Client Application Code

You can use the WebBrowser control to add existing dynamic HTML (DHTML) Web application code to your Windows Forms client applications. This is useful when you have invested significant development time in creating DHTML-based controls and you want to take advantage of the rich user interface capabilities of Windows Forms without having to rewrite existing code.

The WebBrowser control lets you implement two-way communication between your client application code and your Web page scripting code through the ObjectForScripting and Document properties. Additionally, you can configure the WebBrowser control so that your Web controls blend seamlessly with other controls on your application form, hiding their DHTML implementation. To seamlessly blend the controls, format the page displayed so that its background color and visual style match the rest of the form, and use the AllowWebBrowserDrop, IsWebBrowserContextMenuEnabled, and WebBrowserShortcutsEnabled properties to disable standard browser features.

To embed DHTML in your Windows Forms application

  1. Set the WebBrowser control's AllowWebBrowserDrop property to false to prevent the WebBrowser control from opening files dropped onto it.

    webBrowser1.AllowWebBrowserDrop = False
    
    webBrowser1.AllowWebBrowserDrop = false;
    
  2. Set the control's IsWebBrowserContextMenuEnabled property to false to prevent the WebBrowser control from displaying its shortcut menu when the user right-clicks it.

    webBrowser1.IsWebBrowserContextMenuEnabled = False
    
    webBrowser1.IsWebBrowserContextMenuEnabled = false;
    
  3. Set the control's WebBrowserShortcutsEnabled property to false to prevent the WebBrowser control from responding to shortcut keys.

    webBrowser1.WebBrowserShortcutsEnabled = False
    
    webBrowser1.WebBrowserShortcutsEnabled = false;
    
  4. Set the ObjectForScripting property in the form's constructor or a Load event handler.

    The following code uses the form class itself for the scripting object.

    NoteNote

    Component Object Model (COM) must be able to access the scripting object. To make your form visible to COM, add the ComVisibleAttribute attribute to your form class.

    webBrowser1.ObjectForScripting = Me
    
    webBrowser1.ObjectForScripting = this;
    
  5. Implement public properties or methods in your application code that your script code will use.

    For example, if you use the form class for the scripting object, add the following code to your form class.

    Public Sub Test(ByVal message As String)
        MessageBox.Show(message, "client code")
    End Sub
    
    public void Test(String message)
    {
        MessageBox.Show(message, "client code");
    }
    
  6. Use the window.external object in your scripting code to access public properties and methods of the specified object.

    The following HTML code demonstrates how to call a method on the scripting object from a button click. Copy this code into the BODY element of an HTML document that you load using the control's Navigate method or that you assign to the control's DocumentText property.

    <button onclick="window.external.Test('called from script code')">
        call client code from script code
    </button>
    
  7. Implement functions in your script code that your application code will use.

    The following HTML SCRIPT element provides an example function. Copy this code into the HEAD element of an HTML document that you load using the control's Navigate method or that you assign to the control's DocumentText property.

    <script>
    function test(message) { 
        alert(message); 
    }
    </script>
    
  8. Use the Document property to access the script code from your client application code.

    For example, add the following code to a button Click event handler.

    webBrowser1.Document.InvokeScript("test", _
        New String() {"called from client code"})
    
    webBrowser1.Document.InvokeScript("test",
        new String[] { "called from client code" });
    
  9. When you are finished debugging your DHTML, set the control's ScriptErrorsSuppressed property to true to prevent the WebBrowser control from displaying error messages for script code problems.

    ' Uncomment the following line when you are finished debugging.
    'webBrowser1.ScriptErrorsSuppressed = True
    
    // Uncomment the following line when you are finished debugging.
    //webBrowser1.ScriptErrorsSuppressed = true;
    

Example

The following complete code example provides a demonstration application that you can use to understand this feature. The HTML code is loaded into the WebBrowser control through the DocumentText property instead of being loaded from a separate HTML file.

Imports System
Imports System.Windows.Forms
Imports System.Security.Permissions

<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class Form1
    Inherits Form

    Private webBrowser1 As New WebBrowser()
    Private WithEvents button1 As New Button()

    <STAThread()> _
    Public Shared Sub Main()
        Application.EnableVisualStyles()
        Application.Run(New Form1())
    End Sub

    Public Sub New()
        button1.Text = "call script code from client code"
        button1.Dock = DockStyle.Top
        webBrowser1.Dock = DockStyle.Fill
        Controls.Add(webBrowser1)
        Controls.Add(button1)
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Me.Load

        webBrowser1.AllowWebBrowserDrop = False
        webBrowser1.IsWebBrowserContextMenuEnabled = False
        webBrowser1.WebBrowserShortcutsEnabled = False
        webBrowser1.ObjectForScripting = Me
        ' Uncomment the following line when you are finished debugging.
        'webBrowser1.ScriptErrorsSuppressed = True

        webBrowser1.DocumentText = _
            "<html><head><script>" & _
            "function test(message) { alert(message); }" & _
            "</script></head><body><button " & _
            "onclick=""window.external.Test('called from script code')"" > " & _
            "call client code from script code</button>" & _
            "</body></html>"
    End Sub

    Public Sub Test(ByVal message As String)
        MessageBox.Show(message, "client code")
    End Sub

    Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
        Handles button1.Click

        webBrowser1.Document.InvokeScript("test", _
            New String() {"called from client code"})

    End Sub

End Class
using System;
using System.Windows.Forms;
using System.Security.Permissions;

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{
    private WebBrowser webBrowser1 = new WebBrowser();
    private Button button1 = new Button();

    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }

    public Form1()
    {
        button1.Text = "call script code from client code";
        button1.Dock = DockStyle.Top;
        button1.Click += new EventHandler(button1_Click);
        webBrowser1.Dock = DockStyle.Fill;
        Controls.Add(webBrowser1);
        Controls.Add(button1);
        Load += new EventHandler(Form1_Load);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        webBrowser1.AllowWebBrowserDrop = false;
        webBrowser1.IsWebBrowserContextMenuEnabled = false;
        webBrowser1.WebBrowserShortcutsEnabled = false;
        webBrowser1.ObjectForScripting = this;
        // Uncomment the following line when you are finished debugging.
        //webBrowser1.ScriptErrorsSuppressed = true;

        webBrowser1.DocumentText =
            "<html><head><script>" +
            "function test(message) { alert(message); }" +
            "</script></head><body><button " +
            "onclick=\"window.external.Test('called from script code')\">" +
            "call client code from script code</button>" +
            "</body></html>";
    }

    public void Test(String message)
    {
        MessageBox.Show(message, "client code");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        webBrowser1.Document.InvokeScript("test",
            new String[] { "called from client code" });
    }

}

Compiling the Code

This code requires:

  • References to the System and System.Windows.Forms assemblies.

For information about building this example from the command line for Visual Basic or Visual C#, see Building from the Command Line (Visual Basic) or Command-Line Building. You can also build this example in Visual Studio by pasting the code into a new project. How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio

See Also

Reference

WebBrowser
System.Windows.Forms.WebBrowser.Document
System.Windows.Forms.WebBrowser.ObjectForScripting

Other Resources

WebBrowser Control (Windows Forms)