17

I have read WebBrowser Control from .Net — How to Inject Javascript, Is it possible to call Javascript method from C# winforms and many others. Those examples were returns function value or alert window (synchronous calls). I have to get result from event handler (async call):

<script type="text/javascript">
        window.onload = function() {
            var o = new M.Build(document.getElementById("ZID"));

            M.Events.observe(o, o.Events.Success, function() {
                // I have to get some value!!
            });

            M.Events.observe(o, o.Events.Fault, function() {
                // I have to get some value!!
            });
        }
    </script>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
garik
  • 5,669
  • 5
  • 30
  • 42

3 Answers3

33

Calling C# from JavaScript

Simply put, you can expose a C# object to the WebBrowser that the JavaScript can call directly The WebBrowser class exposes a property called ObjectForScripting that can be set by your application and becomes the window.external object within JavaScript. The object must have the ComVisibleAttribute set true

C#:

 [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public class ScriptInterface
    {
        public void callMe()
        {
            … // Do something interesting
        }
    }

    webBrowser1.ObjectForScripting = new ScriptInterface();

Javascript:

window.external.callMe();

Calling JavaScript in a WebBrowser control from C#

garik
  • 5,669
  • 5
  • 30
  • 42
  • 1
    I assume the reason is because you can then inject js code to watch the event, and then have that js call back to your c# code. That's what I'm about to try anyway. – Robert Christ Feb 24 '14 at 21:10
1

This is code I have. In the DocumentCompleted event ('cause I'm getting a page from online)

var wb = (WebBrowser)sender
//Lots of other stuff
object obj = wb.Document.InvokeScript("MyFunctionName");

Create a function that returns whatever value you need and invoke away.

You can also inject a script into the page

string js = "function MyFunctionName(){alert('Yea!');}";
HtmlElement el = wb.Document.CreateElement("script");
IHTMLScriptElement element2 = (IHTMLScriptElement)el.DomElement;
element2.text = js;
head.AppendChild(el);

which can then be invoked. That's what I've done.

QuinnG
  • 6,346
  • 2
  • 39
  • 47
  • o.Events.Success will be fired asynchronously. it's not a solution. – garik Mar 02 '11 at 16:31
  • I was thinking you could assign the value you need to a variable and then have or inject a function that returns that value. – QuinnG Mar 02 '11 at 20:43
  • The question is: when should I invoke this function. I don't know the time when the event would be executed. :( – garik Mar 03 '11 at 10:28
  • If the function that returned the value that you invoke returns some form of an identifier when the value hasn't been set, then you'll know it hasn't been run yet. Without some type of indicator, you can't know if the function has run yet. – QuinnG Mar 03 '11 at 15:44
0

If your webBrowser control is in a form, you can do the following:

[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1
{

    public Form1()
    {
       InitializeComponent();
       webBrowser1.ObjectForScripting = this;
    }

    public void CallMe()
    {
        //.... this method can be called in javascript via window.external.CallMe();
    }
}
Ahmad
  • 8,811
  • 11
  • 76
  • 141