1

In my WPF application I used a webbrowser control to load my local HTML page. I want to call function from c#(WPF App). This is working if javascript is written in HTML but if javascript is in some external file(myscript.js) then exception is throwing when calling js function from c#.

In this code on login button a function of c# is called and from that function a javascript function is called to fill string in unsername input field.

Here is my code.

myscript.js, style.css, test.html

<script type="text/javascript">
    function fillData(data)
    {
        var oVDiv = document.getElementById("uname");
        oVDiv.value = data;
    }
</script>
*,
*:before,
*:after {
    box-sizing: border-box;
}
/*body{background-color:lightblue;}*/
form {
    border: 1px solid #c6c7cc;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -o-border-radius: 5px;
    -moz-border-radius: 5px;
    font: 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
    overflow: hidden;
    width: 240px;
}

fieldset {
    border: 0;
    margin: 0;
    padding: 0;
}

input {
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -o-border-radius: 5px;
    font: 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
    margin: 0;
}

.account-info {
    padding: 20px 20px 0 20px;
}

    .account-info label {
        color: #395870;
        display: block;
        font-weight: bold;
        margin-bottom: 20px;
    }

    .account-info input {
        background: #fff;
        border: 1px solid #c6c7cc;
        box-shadow: inset 0 1px 1px rgba(0, 0, 0, .1);
        -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .1);
        -o-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .1);
        -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .1);
        color: #636466;
        padding: 6px;
        margin-top: 6px;
        width: 100%;
    }

.account-action {
    background: #f0f0f2;
    border-top: 1px solid #c6c7cc;
    padding: 20px;
}

    .account-action .btn {
        background: linear-gradient(#49708f, #293f50);
        border: 0;
        color: #fff;
        cursor: pointer;
        font-weight: bold;
        float: left;
        padding: 8px 16px;
    }

    .account-action label {
        color: #7c7c80;
        font-size: 12px;
        float: left;
        margin: 10px 0 0 20px;
    }
/* .squaredFour */
.squaredFour {
    width: 14px;
    position: relative;
    margin: -2px auto;
}

    .squaredFour label {
        width: 20px;
        height: 20px;
        cursor: pointer;
        position: absolute;
        top: 0;
        left: 0;
        background: #fcfff4;
        background: -webkit-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
        background: linear-gradient(to bottom, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
        border-radius: 4px;
        box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0, 0, 0, 0.5);
    }

        .squaredFour label:after {
            content: '';
            width: 9px;
            height: 5px;
            position: absolute;
            top: 6px;
            left: 4px;
            border: 3px solid #333;
            border-top: none;
            border-right: none;
            background: transparent;
            opacity: 0;
            -webkit-transform: rotate(-45deg);
            transform: rotate(-45deg);
        }
    /*.squaredFour label:hover::after {
  opacity: 0.5;
}*/
    .squaredFour input[type=checkbox] {
        visibility: hidden;
    }

        .squaredFour input[type=checkbox]:checked + label:after {
            opacity: 1;
        }

/* end .squaredFour */
* {
    box-sizing: border-box;
}
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html oncontextmenu="return false";>
<head>
<title>Testing</title>
 <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE11,IE=9; IE=8; IE=7; IE=EDGE"/>
<link rel="stylesheet" type="text/css" href="style.css">
    <script src="myscripts.js"></script>
</head>
<body >
<center>
<h1 style="font-family:arial;"> Please fill User and Password</h1>
<form  >
  <fieldset class="account-info" >
    <label>
      Username
      <input  type="text"  id='uname' />
    </label>
    <label>
      Password
      <input type="password" name="password">
    </label>
  </fieldset>
  <fieldset class="account-action">
    <input class="btn" type="button" name="submit" value="Login" onclick="javascript:window.external.InvokeMeFromJavascript(document.getElementById('uname').value);">
   <div class="squaredFour">
      <input type="checkbox" value="None" id="squaredFour" name="check" checked  />
      <label for="squaredFour"></label>
    </div>
  </fieldset>
</form>
</center>
</body>
</html>

ScriptHeper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Windows;

namespace test
{

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    [ComVisible(true)]
    public class ScriptHelper
    {
        MainWindow mExternalWPF;
        public ScriptHelper(MainWindow w)
        {
            this.mExternalWPF = w;
        }
        public void InvokeMeFromJavascript(string jsscript)
        {
            //this.mExternalWPF.tbMessageFromBrowser.Text = string.Format("Message :{0}", jsscript);
            MessageBox.Show( jsscript,"Error1213", MessageBoxButton.YesNo, MessageBoxImage.Error);
            Object[] objArray = new Object[1];
            objArray[0] = (Object)"text will be filled in username input field";
            this.mExternalWPF.webBrowser.InvokeScript("fillData", objArray);// calling java script function(this call is not working when javascript is in some external file)

        }
    }
}

MainWindow.xaml.cs

using mshtml;
using System;
using System.IO;
using System.Windows;

namespace test
{
    [System.Runtime.InteropServices.ComVisible(true)]
    //[DllImport("TestDLL.dll", CharSet = CharSet.Auto)]
    //public static extern void DisplayMsg();
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ScriptHelper helper = new ScriptHelper(this);
            this.webBrowser.ObjectForScripting = helper;

        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            string curdir = Directory.GetCurrentDirectory();
            webBrowser.Navigate(String.Format("file:///{0}/test.html",curdir));           
        }
    }
}

MainWindow.xaml

<Window x:Class="test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:test"
        mc:Ignorable="d"
        Title="MainWindow" Height="716.157" Width="1307.699" Loaded="Window_Loaded" BorderThickness="0" MinWidth="500" MinHeight="497">
    <Grid>
        <WebBrowser x:Name="webBrowser" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5" ObjectForScripting="HtmlInteropClass">
        <WebBrowser.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="-0.018"/>
                <TranslateTransform/>
            </TransformGroup>
        </WebBrowser.RenderTransform>
        </WebBrowser>
    </Grid>
</Window>

Any help will be appreciated.

Thank You

1 Answer 1

4

Remove the <script> tags from your external JS file and handle the LoadCompleted event for the WebBrowser control. You can call your JS method from there using the InvokeScript method:

MainWindow.xaml.cs:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    string curdir = Directory.GetCurrentDirectory();
    webBrowser.Navigate(String.Format("file:///{0}/test.html", curdir));
    webBrowser.LoadCompleted += (ss, ee) =>
    {
        var jsCode = "fillData('data...');";
        dynamic doc = webBrowser.Document;
        webBrowser.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
    };
}

myscripts.js:

function fillData(data)
{
    //document.getElementById("uname").value = data;
    var oVDiv = document.getElementById("uname");
    //oVDiv.setAttribute("vaue", data);
    oVDiv.value = data;

    //oVDiv.value = data;
    //document.write(data);
}
Sign up to request clarification or add additional context in comments.

1 Comment

what is "execScript" here?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.