NanUI文档 - 如何实现C#与Javascript的相互通信

日期:2019-09-11编辑作者:信长野望

简言之的运用示范

地点的篇章中示范了什么样用C#来调用Javascript中的函数,那么下边的原委将介绍怎样利用Javascript来调用C#中的对象、属性和种种办法。

从前,必要介绍NanUI窗体基类Formium中的主要性质GlobalObject,您可以把他领略成Javascript碰到中的window指标。借使你须求在Javascript碰到下使用C#NanUI文档 - 如何实现C#与Javascript的相互通信。中的各样对象、属性和措施,都亟待将那一个指标、属性、方法注册到GlobalObject里。

上面的例子,通过在Form1的构造函数中注册一个名称叫NanUI文档 - 如何实现C#与Javascript的相互通信。my的JS对象,并在my松开二个只读属性NanUI文档 - 如何实现C#与Javascript的相互通信。name,以及showCSharpMessageBoxNanUI文档 - 如何实现C#与Javascript的相互通信。、getArrayFromCSharpgetObjectFromCSharp多少个函数。

//register the "my" object
var myObject = GlobalObject.AddObject("my");

//add property "name" to my, you should implemnt the getter/setter of name property by using PropertyGet/PropertySet events.
var nameProp = myObject.AddDynamicProperty("name");
nameProp.PropertyGet += (prop, args) =>
{
    // getter - if js code "my.name" executes, it'll get the string "NanUI". 
    args.Retval = CfrV8Value.CreateString("NanUI");
    args.SetReturnValue(true);
};
nameProp.PropertySet += (prop, args) =>
{
    // setter's value from js context, here we do nothing, so it will store or igrone by your mind.
    var value = args.Value;
    args.SetReturnValue(true);
};


//add a function showCSharpMessageBox
var showMessageBoxFunc = myObject.AddFunction("showCSharpMessageBox");
showMessageBoxFunc.Execute += (func, args) =>
{
    //it will be raised by js code "my.showCSharpMessageBox(`some text`)" executed.
    //get the first string argument in Arguments, it pass by js function.
    var stringArgument = args.Arguments.FirstOrDefault(p => p.IsString);

    if (stringArgument != null)
    {
        MessageBox.Show(this, stringArgument.StringValue, "C# Messagebox", MessageBoxButtons.OK, MessageBoxIcon.Information);


    }
};

//add a function getArrayFromCSharp, this function has an argument, it will combind C# string array with js array and return to js context.
var friends = new string[] { "Mr.JSON", "Mr.Lee", "Mr.BONG" };

var getArrayFromCSFunc = myObject.AddFunction("getArrayFromCSharp");

getArrayFromCSFunc.Execute += (func, args) =>
{
    var jsArray = args.Arguments.FirstOrDefault(p => p.IsArray);



    if (jsArray == null)
    {
        jsArray = CfrV8Value.CreateArray(friends.Length);
        for (int i = 0; i < friends.Length; i++)
        {
            jsArray.SetValue(i, CfrV8Value.CreateString(friends[i]));
        }
    }
    else
    {
        var newArray = CfrV8Value.CreateArray(jsArray.ArrayLength + friends.Length);

        for (int i = 0; i < jsArray.ArrayLength; i++)
        {
            newArray.SetValue(i, jsArray.GetValue(i));
        }

        var jsArrayLength = jsArray.ArrayLength;

        for (int i = 0; i < friends.Length; i++)
        {
            newArray.SetValue(i + jsArrayLength, CfrV8Value.CreateString(friends[i]));
        }


        jsArray = newArray;
    }


    //return the array to js context

    args.SetReturnValue(jsArray);

    //in js context, use code "my.getArrayFromCSharp()" will get an array like ["Mr.JSON", "Mr.Lee", "Mr.BONG"]
};

//add a function getObjectFromCSharp, this function has no arguments, but it will return a Object to js context.
var getObjectFormCSFunc = myObject.AddFunction("getObjectFromCSharp");
getObjectFormCSFunc.Execute += (func, args) =>
{
    //create the CfrV8Value object and the accssor of this Object.
    var jsObjectAccessor = new CfrV8Accessor();
    var jsObject = CfrV8Value.CreateObject(jsObjectAccessor);

    //create a CfrV8Value array
    var jsArray = CfrV8Value.CreateArray(friends.Length);

    for (int i = 0; i < friends.Length; i++)
    {
        jsArray.SetValue(i, CfrV8Value.CreateString(friends[i]));
    }

    jsObject.SetValue("libName", CfrV8Value.CreateString("NanUI"), CfxV8PropertyAttribute.ReadOnly);
    jsObject.SetValue("friends", jsArray, CfxV8PropertyAttribute.DontDelete);


    args.SetReturnValue(jsObject);

    //in js context, use code "my.getObjectFromCSharp()" will get an object like { friends:["Mr.JSON", "Mr.Lee", "Mr.BONG"], libName:"NanUI" }
};

运转项目开拓CEF的DevTools窗口,在Console中输入my,就会看出my对象的详细音讯。

图片 1

执行my.showCSharpMessageBox("SOME TEXT FROM JS")NanUI文档 - 如何实现C#与Javascript的相互通信。命令,将调用C#的MessageBox来具体JS函数中提供的“SOME TEXT FROM JS”字样。

执行my.getArrayFromCSharp()能够从C#中取到大家松手的字符串数组中的四个字符串。纵然在函数中钦点了四个数组作为参数,那么钦点的那些数组将和C#的字符串数组合併。

> my.getArrayFromCSharp()
["Mr.JSON", "Mr.Lee", "Mr.BONG"]

> my.getArrayFromCSharp(["Js_Bison", "Js_Dick"])
["Js_Bison", "Js_Dick", "Mr.JSON", "Mr.Lee", "Mr.BONG"]

执行my.getObjectFromCSharp()能够从C#回到我们拼装的目的,该对象有一个字符型的libName属性,以及一个字符串数组friends

> my.getObjectFromCSharp()
Object {libName: "NanUI", friends: Array(3)}

  • NanUI简介
  • 最初使用NanUI
  • 包装并动用内嵌式的HTML/CSS/JS资源
  • 使用网页来安排总体窗口
  • 怎么样完毕C#与Javascript的相互通讯
  • 哪些管理NanUI中的下载进度 - DonwloadHandler的接纳(待更新。。。)
  • 怎么管理NanUI中的弹窗进程 - LifeSpanHandler的利用(待更新。。。)
  • 怎么样决定Javascript对话框 - JsDialogHandler的施用(待更新。。。)
  • 自定义财富管理程序 (待更新。。。)

内需获得再次来到值的情景

上面包车型大巴例子中经过ExecuteJavascript办法来得逞调用了JS情状中的函数。但轻便窥见,这种调用格局C#是未曾抽出到其余重返值的。但实在的连串里,大家是必要从JS境况得到到再次来到值的,那时候使用ExecuteJavascript将不可能知足须要,使用其它三个方式EvaluateJavascript可以帮忙我们从JS意况中收获JS函数的重回值。

假若有别的贰个Javascript函数sayHelloToSomeone,它能吸收接纳一个字符传参数,在函数体中拼接并回到拼接后的字符串。

function sayHelloToSomeone(who) {
    return "Hello " + who + "!";
}

同等的,在地点例子LoadHandler的OnLoadEnd事件中我们来施行sayHelloToSomeone,并通过C#传递参数并赢得拼接后的再次来到值。EvaluateJavascript方法通过叁个回调Action来获得JS遭逢中的再次回到值。那个Action有五个参数,第三个是再次回到值的集聚,第一个是JS情况的十二分对象,借使函数准确实施,那么第二个参数为null

namespace CommunicateBetweenJsAndCSharp
{
    using NetDimension.NanUI;
    public partial class Form1 : Formium
    {
        public Form1()
            : base("http://res.app.local/www/index.html",false)
        {
            InitializeComponent();

            LoadHandler.OnLoadEnd += LoadHandler_OnLoadEnd;
        }

        private void LoadHandler_OnLoadEnd(object sender, Chromium.Event.CfxOnLoadEndEventArgs e)
        {
            // Check if it is the main frame when page has loaded.
            if(e.Frame.IsMain)
            {
                EvaluateJavascript("sayHelloToSomeone('C#')", (value, exception) =>
                {
                    if(value.IsString)
                    {
                        // Get value from Javascript.
                        var jsValue = value.StringValue;

                        MessageBox.Show(jsValue);
                    }
                });
            }
        }
    }
}

在上头的亲自过问中,通过大家能够分明驾驭JS函数sayHelloToSomeone的重返值一定为String类型,由此在C#的回调中央市直机关接运用Value的StringValue属性来获得JS函数的字符传重回值。但在骨子里的利用中,有非常大也许并不完全明白重临值的项目,因而须要选用Value中放置的逐条剖断属性来家家户户筛选再次来到值。

须求注意的是,Value的类是是ChromiumFX中的CfrV8Value体系,它是二个不行重要的品种,基本上全数在C#与CEF间的通讯都以由那些体系来完结的。


社会群众体育和救助

GitHub

交流群QQ群
521854872

赞助小编

假若您欣赏笔者的做事,並且愿意NanUI持续的向上,请对NanUI项目实行帮衬以此来鼓励和支撑作者连续NanUI的费用工作。你能够利用微信或者支付宝来围观下边包车型大巴二维码进行帮助。

图片 2

Javascript调用C#对象及格局

NanUI文档目录

什么贯彻C#与Javascript的交互通信

通过事先的小说,相信您曾经对NanUI有了开班的垂询。但到近来截至,大家利用NanUI仅仅只是当作展现HTML分界面包车型大巴容器,并未有涉及CEF与C#间数据的互动。那么本文将简要介绍怎么样在NanUI中使用C#调用Javascript的函数以及哪些在Javascript注入C#的指标、属性和办法。

回调函数

回调函数是Javascript里面主要和常用的效应,假使您在JS境遇中登记的格局具有函数型的参数(即回调函数),通过Execute事件的Arguments能够获取回调的function,并动用CfrV8Value的ExecuteFunction来实施回调。

//add a function with callback function

var callbackTestFunc = GlobalObject.AddFunction("callbackTest");
callbackTestFunc.Execute += (func,args)=> {
    var callback = args.Arguments.FirstOrDefault(p => p.IsFunction);
    if(callback != null)
    {
        var callbackArgs = CfrV8Value.CreateObject(new CfrV8Accessor());
        callbackArgs.SetValue("success", CfrV8Value.CreateBool(true), CfxV8PropertyAttribute.ReadOnly);
        callbackArgs.SetValue("text", CfrV8Value.CreateString("Message from C#"), CfxV8PropertyAttribute.ReadOnly);

        callback.ExecuteFunction(null, new CfrV8Value[] { callbackArgs });
    }
};

在Console中执行callbackTest(function(result){ console.log(result); })将推行无名氏回调,并获取到C#回传的result对象。

> callbackTest(function(result){ console.log(result); })
Object {success: true, text: "Message from C#"}

在大多数情形下,在Javascript中回调都以因为实践了一部分异步的操作,那么一旦那几个异步的操作是在C#实践也是立见成效的,只是达成起来就相比复杂。下边将演示怎样促成四个异步回调。

//add a function with async callback
var asyncCallbackTestFunc = GlobalObject.AddFunction("asyncCallbackTest");
asyncCallbackTestFunc.Execute += async (func, args) => {
//save current context
var v8Context = CfrV8Context.GetCurrentContext();
var callback = args.Arguments.FirstOrDefault(p => p.IsFunction);

//simulate async methods.
await Task.Delay(5000);

if (callback != null)
{
    //get render process context
    var rc = callback.CreateRemoteCallContext();

    //enter render process
    rc.Enter();

    //create render task
    var task = new CfrTask();
    task.Execute += (_, taskArgs) =>
    {
        //enter saved context
        v8Context.Enter();

        //create callback argument
        var callbackArgs = CfrV8Value.CreateObject(new CfrV8Accessor());
        callbackArgs.SetValue("success", CfrV8Value.CreateBool(true), CfxV8PropertyAttribute.ReadOnly);
        callbackArgs.SetValue("text", CfrV8Value.CreateString("Message from C#"), CfxV8PropertyAttribute.ReadOnly);

        //execute callback
        callback.ExecuteFunction(null, new CfrV8Value[] { callbackArgs });


        v8Context.Exit();

        //lock task from gc
        lock (task)
        {
            Monitor.PulseAll(task);
        }
    };

    lock (task)
    {
        //post task to render process
        v8Context.TaskRunner.PostTask(task);
    }

    rc.Exit();

    GC.KeepAlive(task);
}

在Console中执行asyncCallbackTest(function(result){ console.log(result); })将执行无名回调,大致5秒后拿走到C#回传的result对象。

> asyncCallbackTest(function(result){ console.log(result); })
Object {success: true, text: "Message from C#"}

如上,您曾经简单精通了使用NanUI怎么做到C#和Javascript的交互通讯。NanUI基于开源项目ChromiumFX开采,由此C#与Javascript的相互与ChomiumFX保持一致,假如急需开拓越发千头万绪的效果与利益,请自行检索和参照ChromiumFX的相关API及示范。

无需获得再次来到值的景色

纵然页面中如同下Javascript的函数sayHello,它的功能是在DOM中开创叁个分包有“Hello NanUI!”字样的p元素。

function sayHello() {
    var p = document.createElement("p");
    p.innerText = "Hello NanUI!";

    var container = document.getElementById("hello-container");
    container.appendChild(p);
}

演示中,该函数并从未在Javascript景况里调用,而是在页面加载成功后接纳NanUI的ExecuteJavascript措施来调用它。ExecuteJavascript格局实施的归来结果为叁个bool类型,它提示了此次有未遂实施。

在窗体的构造函数中,通过挂号Formium的LoadHandler中的OnLoadEnd事件来监测页面加载成功的状态,并在页面加载成功后调用JS蒙受中的函数sayHello。

namespace CommunicateBetweenJsAndCSharp
{
    using NetDimension.NanUI;
    public partial class Form1 : Formium
    {
        public Form1()
            : base("http://res.app.local/www/index.html",false)
        {
            InitializeComponent();

            LoadHandler.OnLoadEnd += LoadHandler_OnLoadEnd;
        }

        private void LoadHandler_OnLoadEnd(object sender, Chromium.Event.CfxOnLoadEndEventArgs e)
        {
            // Check if it is the main frame when page has loaded.
            if(e.Frame.IsMain)
            {
                ExecuteJavascript("sayHello()");
            }
        }
    }
}

运维后,能够看到分界面中显得了“Hello NanUI!”字样,表明使用ExecuteJavascript可以调用JS函数。


示范源码

git clone https://github.com/NetDimension/NanUI-Examples-04-Communicate-Between-CSharp-And-JS.git

C#调用Javascript函数

本文由云顶国际登录官网发布于信长野望,转载请注明出处:NanUI文档 - 如何实现C#与Javascript的相互通信

关键词:

信长野望为什么有人仿天蚕土豆的书,却没人仿

信长野望为什么有人仿天蚕土豆的书,却没人仿唐家三少的书呢?。信长野望为什么有人仿天蚕土豆的书,却没人仿...

详细>>

唐家三少妻子去世,为什么引得无数人泪奔?

三少是最早一批网络写手之一,一同走过来,能坚持下来的没有多少人。 问题: 9月11日深夜23时57分,微博认证为中...

详细>>

还珠楼主的小说有多强?

问题: 还珠楼主的小说有多强? 还珠楼主的小说有多强?。还珠楼主的小说有多强?。回答: 说起还珠楼主,可能...

详细>>

信长野望古龙和金庸,你更喜欢谁?为什么?

回答: 还有,古龙小说大多是片段,悬疑不断,扣人心弦,融合了推理与武侠的两大长处,看起来耿过瘾。 这可把我...

详细>>