views:

3682

answers:

5

We have a windows application that contains an ActiveX WebBrowser control. As part of the regular operation of this application modifications are made to the pages that are displayed by the ActiveX WebBrowser control. Part of these modifications involve setting a JavaScript variable in a web page being loaded into the ActiveX WebBrowser.

We need to initialize this variable within C# (originally, VB6 code was initializing the value). The value of this variable is a COM-visible class object.

However, for simplicity we've reduced the problem to setting a string value. Our original page involves frames and the like but the same problems happens in a page like this:

<HTML>
 <HEAD>
  <TITLE>Test</TITLE>
  <SCRIPT type="text/javascript">
   var field = 'hello world';
  </SCRIPT>
 </HEAD>
 <BODY>
   <input type="button" value="See field" onclick="javascript:alert(field);"/>
 </BODY>
</HTML>

We want to access the field variable and assign a value to it. In VB6 the code for this was pretty straightforward:

doc.Script.field = 'newValue'

However, in C# we've had to resort to other tricks, like this:

Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateSet(Script, null, "field",new object[] { "newValue"},null, null);

The point of the page is to test whether our variable was properly assigned by C#. Clicking on the button should yield whatever new value was injected by C#. So for example, clicking on the button in the page we get an alert showing: "newValue".

That works the first time, but it doesn't work if we reload the page. On subsequent calls we cannot set the value of the variable field.

Has anyone had any experience doing this type of operation before?

A: 

The usual method we use is to add a hidden text input box (the ASP.Net control version) on the page. That way you can easily set its value in the C# codebehind and read the value in client side JavaScript (and vice-versa, of course).

CMPalmer
+1  A: 

These two articles helped us find a solution to our problem. They outline the basics of what one needs to know:

Microsoft Web Browser Automation using C#

Using MSHTML Advanced Hosting Interfaces

So we implemented a DocHostUIHandler interface and that allowed us to set a UIHandler, allowing us to reference the method from Javascript.

Esteban Brenes
+1  A: 

If you use the webBrowser control, you can assign a c# object to the objectForScripting property http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting.aspx

after that you can use window.external in your javascript to interact with your c# object from javascript

if you use an activeX version for some reason, you can pass javascript: urls to programmatically sets your variable, or you can syncronize your script using a webservice/ database/file or simply using the method you suggested.

kentaromiura
A: 

Hidden text input that is one smart way thanks for the hint.

A: 

I think what you are looking for is eval() method in Javascript. You can call it from C# e.g. like this webBrowser1.Document.InvokeScript("eval", new String[] {"1 + 2"}); This code will evaluate "1 + 2" and return "3". I would imagine that if you were to put in InvokeScript("eval", new String[] {"varName = 3"}) you would get that variable assigned to 3 if it is globally visible in the file.

EndangeringSpecies