Silverlight与HTML页面交互基本方法总结


======================================================
注:本文源代码点此下载
======================================================

silverlight与html页面的交互功能是通过统称为html bridge的一组类型和方法来实现的。要启用交互功能需要在创建silverlight控件时指定enablehtmlaccess参数为true,否则很多方法的使用都会引发异常。

在object标签式创建方法中为:

param name="enablehtmlaccess" value="true" />

silverlight直接控制html

在silverlight中可以使用system.windows.browser命名空间中的类和方法来操作html,主要涉及以下几个类:

browserinformation - 代表浏览器及客户端操作系统相关信息

htmldocument - 代表浏览器中的html文档

htmlelement - 代表了一个html元素

htmlpage - 提供了操作dom的方法

htmlwindow - 代表javascript中的window

其中,最重要的就是htmlpage类,它提供了一组静态方法来获取其他类的实例,如:

取得browserinformation:

browserinformation browserinfo = htmlpage.browserinformation;

取得htmldocument:

htmldocument htmldocument = htmlpage.document;

取得htmlwindow:

htmlwindow htmlwindow = htmlpage.window;

下面列举一些常用操作:

在新窗口中打开网页:

htmlpage.window.navigate(new uri("https://www.google.com"), "__blank");

修改页面标题:

htmlpage.document.setproperty("title", "new title");

修改、取得页面元素属性:

htmlelement elem = htmlpage.document.getelementbyid("elem1");

elem.setattribute("value", "haha");

string value = elem.getattribute("value");

注册html元素事件:

elem.attachevent("onclick", delegate(object sender, htmleventargs he)

{

// ...

});

javascript中调用silverlight方法/属性

要从javascript中调用silverlight方法,silverlight必须首先注册scriptableobject。这可以通过给要暴露给js的类型加上scriptabletypeattribute,这样就会暴露该类型的所有属性、方法和事件;如果只要暴露一部分成员,也可以仅给这一部分成员标记scriptablememberattribute(在过去的版本中仅有scriptableattribute)。这个标记是非常宽松的,只要类中有成员是scriptable的,就可以使用htmlpage.registerscriptableobject方法来注册这个类使其能被js访问。比如:

public partial class mainpage : usercontrol{public mainpage(){initializecomponent();htmlpage.registerscriptableobject("page", this);}[scriptablemember]public string process(string arg){return "called from js: " + arg;

}

}

在html页面则可以用如下js代码调用process方法:

function callsl() {var slhost = document.getelementbyid("silverlightcontrol");var page = slhost.content.page;alert(page.process('param from js'));}

将callsl方法注册到按钮的onclick上:

input type="button" value="call sl" onclick="callsl()" />

点击运行结果如下:

silverlight属性的调用方法同理。

(附带一提,这里的"silverlightcontrol"是silverlight控件的id,即silverlight的object标签id。)

javascript注册silverlight中的事件

无参数事件

silverlight中,事件用scriptablememberattribute标记或者包含事件的类用scriptabletypeattribute标记后,再用htmlpage.registerscriptableobject注册该类,在javascript中就可以访问该事件。比如silverlight暴露如下事件:

public event eventhandler buttonclicked;

那么在js中可以用下面的代码注册该事件:

function onsilverlightload() {var slhost = document.getelementbyid("silverlightcontrol");var page = slhost.content.page;page.buttonclicked = function () {alert("button clicked in sl.");};

}

那么当用户点击silverlight中的按钮时,就会执行注册的js代码:

值得注意的是,这段js并不能放在页面的onload事件中执行,因为那时silverlight控件可能还没加载完成,应该放在silverlight控件的onload事件中。在silverlight的标签中添加onload参数:

param name="onload" value="onsilverlightload" />

带参数事件

然后是如何传递事件参数的问题,网上许多人说指定自定义参数时,在js中无法获取,提示不支持指定的方法或属性,其实只要将eventargs类本身也指定为scriptabletype即可(当然也可将成员指定为scriptablemember)。示例如下。

事件参数类:

[scriptabletype]public class buttonclickedeventargs : eventargs{public string message { get; set; }}

mainpage类:

public partial class mainpage : usercontrol{

private void button_click(object sender, system.windows.routedeventargs e){

// 引发buttonclicked事件并传入事件参数onbuttonclicked(new buttonclickedeventargs() { message = "message from sl." });}#region [buttonclicked event][scriptablemember]public event eventhandlerbuttonclickedeventargs> buttonclicked;[system.diagnostics.debuggerstepthrough]protected virtual void onbuttonclicked(buttonclickedeventargs e){if(null != buttonclicked){buttonclicked(this, e);}}#endregion}

将js的事件处理函数改成:

page.buttonclicked = function (sender, args) {alert(args.message);};

如此,当点击sl中按钮时结果如下:

可见event args被成功传递了出来。

under the hood

至此基本已满足一般使用的需要了。其实不论是从js调用silverlight方法/属性,或者注册silverlight事件,其本质问题都是如何将托管对象传给javascript,这里面就有一个对象marshal的问题。marshal遵循以下原则:

托管类型通过传递引用的方式传给javascript

javascript类型要传入silverlight,必须要先进行一层托管的封装

如果将托管类型marshal到javascript过程发生错误,抛出invalidoperationexception

如果将javascript数据marshal入silverlight时发生错误,javascript调用者将得到一个异常,异常文本描述了发生的错误

基本类型(即所谓的primitive types)

以下类型属于基本类型,即不需要标记scriptabletypeattribute或者scriptablememberattribute而可以直接在silverlight和js之间传递的类型:

silverlight

javascript

string

字符串

null

null

boolean

boolean

datetime

date

char

单字符的字符串

数字类型

double(来回转换可能引发精度及溢出问题)

枚举

数字

guid

格式化的字符串

除此之外,基本的c#数组或者实现了ilist接口的类型,可以直接转换为javascript中的array;实现了idictionary的类型也可以直接转为javascript中的dictionary。

反过来,javascript中的数组传入silverlight时,一般会被转为object[];dictionary则被转为dictionary.

复杂类型

对于用户创建的复杂类型,则需要通过标记scriptabletypeattribute或者scriptablememberattribute,使其能够正确地传递给javascript.

对于silverlight和javascript间的marshal,以上依然只描述了各种最基本的情形。我也不想做那种照翻msdn的事情,对于更加复杂的情形,以及各种注意事项,可自行参考silverlight and javascript marshaling。

http://silverlightchina.net/html/tips/2010/0709/1466.html


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值