как вызвать функцию js из c # wpf

1

В моем приложении WPF я использовал элемент управления webbrowser для загрузки моей локальной HTML-страницы. Я хочу вызвать функцию из С# (приложение WPF). Это работает, если javascript написан в HTML, но если javascript находится в каком-то внешнем файле (myscript.js), тогда исключение бросает при вызове функции js из С#.

В этом коде на кнопке входа вызывается функция С# и из этой функции вызывается функция javascript для заполнения строки в поле ввода имени пользователя.

Вот мой код.

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>

Любая помощь будет оценена.

Спасибо

Теги:
wpf
webbrowser-control
wpf-controls

1 ответ

2
Лучший ответ

Удалите теги <script> из внешнего файла JS и обработайте событие LoadCompleted для WebBrowser управления WebBrowser. Вы можете вызывать свой JS-метод там, используя метод InvokeScript:

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);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню