1

I have WinForm with WebBrowser control where I open HTML5 + Angular JS (TypeScript) form. I want to call typescript function from my C# code but it is not working with InvokeScirpt() method.

webBrowser1.Document.InvokeScript("method", new object[] {"123", "453")});

I am able to call Javascript method using this way when i load HTML + Javascript page in webbrowser control.

Also, please note typescript function I am able to call from the HTML page I have (on button click)

Could you please suggest whether this is a right way to call typescript function from C# webbrowser control OR I need to try something else?

Thanks,

ManojP
  • 85
  • 1
  • 9
  • As far as I know, typescript methods will compile to javascript methods when you build your application, so to call them, so you can call compiled methods like any other javascript methods. – Reza Aghaei Dec 21 '16 at 14:40
  • correct, I have the same understanding but somehow it is not working. I don't see any option to debug that as well. Any other options O should try here? – ManojP Dec 21 '16 at 14:45
  • 1
    Probably the method which you are trying to call, is method of an object and you can not call it directly. You should first create an instance of that object (using javascript compiled code) and then call the method of the object. – Reza Aghaei Dec 21 '16 at 15:02
  • Thanks. Do you have any example how I can create an instance of that object using javascript compiled code? – ManojP Dec 21 '16 at 15:16
  • 1
    Yes, I added an example. – Reza Aghaei Dec 21 '16 at 22:26
  • Thanks it worked for me. I have added 2 questions below your example. Appreciate if you can provide some more information. Thanks again for your help. – ManojP Dec 22 '16 at 13:52

2 Answers2

3

Typescript methods will compile to javascript methods when you build your application, so to call them, you can call compiled methods like any other javascript methods.

Example

In the example, I suppose you have a app.ts containing this class:

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

And I suppose you have added app.js in index.html add this code:

<html>
<head>
    <script src="app.js"></script>
</head>
<body>
    ...
</body>
</html>

Then in your windows forms application, you can use Greeter this way:

string javascript = "var greeter = new Greeter('World!'); alert(greeter .greet());";
webBrowser1.Document.InvokeScript("eval", new object[] { javascript });
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Thanks this approach worked for me. 2 questions 1. Is there any better approach? This looks like very tightly coupled with my Angular code. Any change in constructor can impact this. 2. What if I have more parameters like $Scope, $State,$windo, $timeout etc.. in constructor? Is it really possible to create an object from my C# code with these type of params or I should create default constructor every time as a workaround? I am new to Angular so not very sure about params $Scope, $State,$windo, $timeout pass into while creating constructor outside of app. Thanks for your help. – ManojP Dec 22 '16 at 13:46
  • You're welcome :) - Unfortunately I'm not familiar with angular and I've no idea about the best way which you can use those parameters, but you can write any javascript code which you need and using `webBrowser1.Document.InvokeScript("eval", new object[] { javascript });` you can run the code and get the result. To communicate between browser control and your windows forms application take a look at [this post](http://stackoverflow.com/a/34840461/3110834). To show modern contents in WebBrowser control take a look at [this post](http://stackoverflow.com/a/38514446/3110834). – Reza Aghaei Dec 22 '16 at 17:35
0

I had a same problem. I wanted to load an Angular 2+ from in WebBrowser control and do form auto fill. So I did as Follow :

  1. In the head section of index.html of Angular 2+ project I add a javascript function.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" /> 
  <base href="/" />
  <title>Test</title>
  <link rel="icon" type="image/x-icon" href="favicon.ico" />
  <script type="text/javascript">
    function callAngularFunction(params) {window.angularComponentReference.zone.run(function (){window.angularComponentReference.LoginLogout(params); }); }                                         
  </script>
  </head>
  <body>
    <app-root>Loading...</app-root>  
  </body>
  </html>
  1. Then in a constructor of a component which I would like the belonging method, response

import { Component, OnInit, NgZone } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
})

export class LoginComponent implements OnInit{
   constructor(private ngZone: NgZone){} 
   ngOnInit() {
      window['angularComponentReference'] = { component: this, zone: this.ngZone, LoginLogout: (params) => this.AutoLogin(params) };
   }
  
   public AutoLogin(params: any){
     //params could be a string with ',' separator
     //then assign each parameter to proper variable in this component
     //which bind to Html fields 
   }
}
  1. In C#

    winWebBrowser.Document.InvokeScript("callAngularFunction", new object[] {"username,password"});

hope it helps.

Ali Tabandeh
  • 86
  • 1
  • 3