NanUI⽂档-如何实现C#与Javascript的相互通信
NanUI⽂档⽬录
-
-
-
-
-
- 如何处理NanUI中的下载过程 - DonwloadHandler的使⽤(待更新。。。)
- 如何处理NanUI中的弹窗过程 - LifeSpanHandler的使⽤(待更新。。。)
- 如何控制Javascript对话框 - JsDialogHandler的使⽤(待更新。。。)
- ⾃定义资源处理程序 (待更新。。。)
如何实现C#与Javascript的相互通信
通过之前的⽂章,相信您已经对NanUI有了初步的了解。但到⽬前为⽌,我们使⽤NanUI仅仅只是作为呈现HTML界⾯的容器,并未涉及CEF与C#间数据的交互。那么本⽂将简单介绍如何在NanUI中使⽤C#调⽤Javascript的函数以及如何在Javascript注⼊C#的对象、属性和⽅法。
C#调⽤Javascript函数
不需要获取返回值的情况
假设页⾯中有如下Javascript的函数sayHello,它的作⽤是在DOM中创建⼀个包含有“Hello NanUI!”字样的p元素。
function sayHello() {
var p = ateElement("p");
p.innerText = "Hello NanUI!";
var container = ElementById("hello-container");
container.appendChild(p);
}
⽰例中,该函数并没有在Javascript环境⾥调⽤,⽽是在页⾯加载完成后使⽤NanUI的ExecuteJavascript⽅法来调⽤它。ExecuteJavascript⽅法执⾏的返回结果为⼀个bool类型,它指⽰了这次有没有成功执⾏。
在窗体的构造函数中,通过注册Formium的LoadHandler中的OnLoadEnd事件来监测页⾯加载完成的情况,并在页⾯加载成功后调⽤JS 环境中的函数sayHello。
{
public Form1()
: base("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函数。
需要获取返回值的情况
上⾯的例⼦中通过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。
{
public Form1()
: base("res.app.local/www/index.html",false)
js arguments
{
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间的通信都是由这个类型来完成的。
Javascript调⽤C#对象及⽅法
简单的应⽤⽰例
上⾯的⽂章中演⽰了如何⽤C#来调⽤Javascript中的函数,那么下⾯的内容将介绍如何使⽤Javascript来调⽤C#中的对象、属性和各种⽅法。
在此之前,需要介绍NanUI窗体基类Formium中的重要属性GlobalObject,您可以把他理解成Javascript环境中的window对象。如果您需要在Javascript环境下使⽤C#中的各种对象、属性和⽅法,都需要将这些对象、属性、⽅法注册到GlobalObject⾥。
下⾯的例⼦,通过在Form1的构造函数中注册⼀个名为my的JS对象,并在my内置⼀个只读属性name,以及showCSharpMessageBox、getArrayFromCSharp、getObjectFromCSharp三个函数。
//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.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) =>
{
//i t will be raised by js code "my.showCSharpMessageBox(`some text`)" executed.
//g et 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);
/
/i n 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);
//i n 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对象的详细信息。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。