
Winform NanUI 0.77版本 JS和C#相互调用
发布日期:2021-05-07 21:45:08
浏览次数:23
分类:精选文章
本文共 10147 字,大约阅读时间需要 33 分钟。
用的NanUI版本0.77
参考官方地址:
基础代码:
using NetDimension.NanUI;using NetDimension.NanUI.Browser;class MainWindow : Formium{ //网页的地址 public override string StartUrl => "https://www.google.com"; //边框模式 public override HostWindowType WindowType => HostWindowType.Standard; //这里写null就好 protected override Control LaunchScreen => null; public MainWindow() { Title = "第一个NanUI应用" } protected override void OnWindowReady(IWebBrowserHandler browserClient) { } protected override void OnRegisterGlobalObject(JSObject global) { } //网页的大小和布局 protected override void OnStandardFormStyle(IStandardHostWindowStyle style) { base.OnStandardFormStyle(style); style.Width = 1280; style.Height = 720; style.Icon = System.Drawing.SystemIcons.WinLogo; style.StartPosition = FormStartPosition.CenterScreen; }}
启动页面也需要修改一下:
using NetDimension.NanUI;static class Program{ ////// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); Bootstrap .Initialize() .Run(() => new MainWindow()); }}
=========================================================================
下面开始实践
一、C# 调用JS
在C#代码中,可以调用界面加载完成后的回调,在里面调用JS代码
C#:
protected override void OnWindowReady(IWebBrowserHandler browserClient){ browserClient.LoadHandler.OnLoadEnd += LoadHandler_OnLoadEnd;}private void LoadHandler_OnLoadEnd(object sender, Chromium.Event.CfxOnLoadEndEventArgs e){ if (e.Frame.IsMain) { //C#调用网页中的JS脚本中sayHollo方法,这里,并没有返回参数,仅仅是让浏览器打印一个log而已 WebBrowser.ExecuteJavascript("sayHollo()"); //C#调用网页中JS脚本 带有返回参数的方法 WebBrowser.EvaluateJavascript("returnValue('C#')", (value, exception) => { if (value.IsString) { var jsValue = value.StringValue; MessageBox.Show(jsValue); } }); }}
这里调用了JS中的两个方法:sayHollo,returnValue
JS:
function sayHollo() { alert("网页alert: Hollo!");}function returnValue() { return "JS 返回 嘻嘻嘻!";}
效果:
二、JS调用C#方法:
C#:
protected override void OnRegisterGlobalObject(JSObject global){ var myObject = global.AddObject("my"); #region 添加属性 //添加一个属性:name var nameProp = myObject.AddDynamicProperty("name"); //Get属性 nameProp.PropertyGet += (prop, args) => { //要返回的字符串 args.Retval = "这是C#的一个Get属性:name"; args.SetReturnValue(true); }; //Set属性 nameProp.PropertySet += (prop, args) => { var value = args.Value; args.SetReturnValue(true); }; #endregion #region 添加方法 //添加一个方法 showCSharpMessageBox var showMessageBoxFunc = myObject.AddFunction("showCSharpMessageBox"); showMessageBoxFunc.Execute += (func, args) => { var stringArgument = args.Arguments.FirstOrDefault(p => p.IsString); if (stringArgument != null) MessageBox.Show(stringArgument.StringValue); else MessageBox.Show("Js传递的参数为空!"); }; //添加一个具有返回参数的方法 var getArrayFromCSFunc = myObject.AddFunction("getArrayFromCSharp"); getArrayFromCSFunc.Execute += (func, args) => { var jsArray = args.Arguments.FirstOrDefault(p => p.IsArray); if (jsArray != null) { //获取数组的长度 int len = jsArray.ArrayLength; //创建一个新的数组 CfrV8Value arr = CfrV8Value.CreateArray(len); for (int i = 0; i < len; i++) { //获取JS传过来数组的值 int v = jsArray.GetValue(i).IntValue; //+1后,放入新的数组 arr.SetValue(i, CfrV8Value.CreateInt(v + 1)); } //作为返回参数 args.SetReturnValue(arr); } }; //接收JS的回调,并将自己的参数传递过去 var callbackTestFunc = myObject.AddFunction("callbackTest"); callbackTestFunc.Execute += (func, args) => { var callback = args.Arguments.FirstOrDefault(p => p.IsFunction); if (callback != null) { //创建一个Object类型的变量 var callbackArgs = CfrV8Value.CreateObject(new CfrV8Accessor()); //添加一个Bool类型的值:success callbackArgs.SetValue("success", CfrV8Value.CreateBool(true), CfxV8PropertyAttribute.ReadOnly); //添加一个string类型的值:text callbackArgs.SetValue("text", CfrV8Value.CreateString("Message from C#"), CfxV8PropertyAttribute.ReadOnly); //用ExecuteFunction执行JS传递过来的回调,并将自己设置的变量callbackArgs传递给JS callback.ExecuteFunction(null, new CfrV8Value[] { callbackArgs }); } }; #endregion}
JS添加一个按钮,用来调用C#注入的方法:
function on_Click() { // alert("点击了按钮"); //调用C#中注入的属性 alert(my.name); //调用C#中注入的方法(无返回值) my.showCSharpMessageBox("我是参数!"); //调用C#中注入的方法(返回一个数组) var arr = [1, 2, 3]; var retArr = my.getArrayFromCSharp(arr); if (retArr) { alert("网页alert:" + retArr); } //调用C#并传入一个JS的回调 my.callbackTest(sayByeBye);};function sayByeBye(obj) { var str = "参数success:" + obj.success + " 参数text:" + obj.text alert("网页alert: " + str);}
完整版C#代码:
using Chromium;using Chromium.Remote;using NetDimension.NanUI;using NetDimension.NanUI.Browser;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace CSharpCallJS{ //参考:https://docs.formium.net/zh-hans/tutorial/js-context.html public class myform1 : Formium { //指定启动时访问的 Url 地址,这里用的是本地地址 public override string StartUrl => @"E:\CSharp Project\NanUI_Test\CSharpCallJS\Viwe\index.html"; //指定 WindowType 属性,选择窗体以原生样式显示还是使用无边框样式 public override HostWindowType WindowType => HostWindowType.Standard; protected override Control LaunchScreen => null; public myform1() { Title = "第一个NanUI应用"; } protected override void OnWindowReady(IWebBrowserHandler browserClient) { browserClient.LoadHandler.OnLoadEnd += LoadHandler_OnLoadEnd; } protected override void OnRegisterGlobalObject(JSObject global) { var myObject = global.AddObject("my"); #region 添加属性 //添加一个属性:name var nameProp = myObject.AddDynamicProperty("name"); //Get属性 nameProp.PropertyGet += (prop, args) => { //要返回的字符串 args.Retval = "这是C#的一个Get属性:name"; args.SetReturnValue(true); }; //Set属性 nameProp.PropertySet += (prop, args) => { var value = args.Value; args.SetReturnValue(true); }; #endregion #region 添加方法 //添加一个方法 showCSharpMessageBox var showMessageBoxFunc = myObject.AddFunction("showCSharpMessageBox"); showMessageBoxFunc.Execute += (func, args) => { var stringArgument = args.Arguments.FirstOrDefault(p => p.IsString); if (stringArgument != null) MessageBox.Show(stringArgument.StringValue); else MessageBox.Show("Js传递的参数为空!"); }; //添加一个具有返回参数的方法 var getArrayFromCSFunc = myObject.AddFunction("getArrayFromCSharp"); getArrayFromCSFunc.Execute += (func, args) => { var jsArray = args.Arguments.FirstOrDefault(p => p.IsArray); if (jsArray != null) { //获取数组的长度 int len = jsArray.ArrayLength; //创建一个新的数组 CfrV8Value arr = CfrV8Value.CreateArray(len); for (int i = 0; i < len; i++) { //获取JS传过来数组的值 int v = jsArray.GetValue(i).IntValue; //+1后,放入新的数组 arr.SetValue(i, CfrV8Value.CreateInt(v + 1)); } //作为返回参数 args.SetReturnValue(arr); } }; //接收JS的回调,并将自己的参数传递过去 var callbackTestFunc = myObject.AddFunction("callbackTest"); callbackTestFunc.Execute += (func, args) => { var callback = args.Arguments.FirstOrDefault(p => p.IsFunction); if (callback != null) { //创建一个Object类型的变量 var callbackArgs = CfrV8Value.CreateObject(new CfrV8Accessor()); //添加一个Bool类型的值:success callbackArgs.SetValue("success", CfrV8Value.CreateBool(true), CfxV8PropertyAttribute.ReadOnly); //添加一个string类型的值:text callbackArgs.SetValue("text", CfrV8Value.CreateString("Message from C#"), CfxV8PropertyAttribute.ReadOnly); //用ExecuteFunction执行JS传递过来的回调,并将自己设置的变量callbackArgs传递给JS callback.ExecuteFunction(null, new CfrV8Value[] { callbackArgs }); } }; #endregion } protected override void OnStandardFormStyle(IStandardHostWindowStyle style) { base.OnStandardFormStyle(style); style.Width = 800; style.Height = 600; style.Icon = System.Drawing.SystemIcons.WinLogo; style.StartPosition = FormStartPosition.CenterScreen; } private void LoadHandler_OnLoadEnd(object sender, Chromium.Event.CfxOnLoadEndEventArgs e) { if (e.Frame.IsMain) { //C#调用网页中的JS脚本中sayHollo方法,这里,并没有返回参数,仅仅是让浏览器打印一个log而已 WebBrowser.ExecuteJavascript("sayHollo()"); //C#调用网页中JS脚本 带有返回参数的方法 WebBrowser.EvaluateJavascript("returnValue('C#')", (value, exception) => { if (value.IsString) { var jsValue = value.StringValue; MessageBox.Show(jsValue); } }); } } }}
完整版JS代码:
Document 我的网页
end
发表评论
最新留言
很好
[***.229.124.182]2025年04月01日 15时01分25秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
C#搞个跨平台的桌面NES游戏模拟器
2019-03-06
手把手教你安装Eclipse最新版本的详细教程 (非常详细,非常实用)
2019-03-06
《带你装B,带你飞》pytest成魔之路4 - fixture 之大解剖
2019-03-06
互联网App应用程序测试流程及测试总结
2019-03-06
根据轨迹分析出用户家在哪
2019-03-06
PostgreSQL查询表名称及表结构
2019-03-06
是什么?评估分类器的常用概念----准确率,精确率,召回率
2019-03-06
linux中使用awk命令
2019-03-06
LAB2 内核的内存管理
2019-03-06
如何使用google搜索?
2019-03-06
Redis分布式锁的正确实现方式
2019-03-06
设计模式-抽象工厂模式
2019-03-06
MySQL Explain查看执行计划详解
2019-03-06
IntelliJ IDEA 中,项目文件右键菜单没有svn选项解决办法
2019-03-06
Spring 动态绑定多实现类实例综述
2019-03-06
IDEA 调试Java代码的两个技巧
2019-03-06
MyBatis常见面试题:#{}和${}的区别是什么?
2019-03-06
Vue 数组和对象更新,但视图未更新,背后的故事
2019-03-06
剑指Offer面试题:9.二进制中1的个数
2019-03-06