silverlight 打开html_Silverlight与HTML页面交互基本方法总结

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

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

Silverlight直接控制HTML

在Silverlight中可以使用System.Windows.Browser命名空间中的类和方法来操作HTML,主要涉及以下几个类:

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

HtmlDocument- 代表浏览器中的HTML文档

HtmlElement- 代表了一个HTML元素

HtmlPage- 提供了操作DOM的方法

HtmlWindow- 代表JavaScript中的window

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

取得BrowserInformation:

BrowserInformationbrowserInfo=HtmlPage.BrowserInformation;

取得HtmlDocument:

HtmlDocumenthtmlDocument=HtmlPage.Document;

取得HtmlWindow:

HtmlWindowhtmlWindow=HtmlPage.Window;

下面列举一些常用操作:

在新窗口中打开网页:

HtmlPage.Window.Navigate(newUri("https://www.google.com"),"__blank");

修改页面标题:

HtmlPage.Document.SetProperty("title","New Title");

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

HtmlElementelem=HtmlPage.Document.GetElementByID("elem1");

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

stringvalue=elem.GetAttribute("value");

注册HTML元素事件:

elem.AttachEvent("onclick",delegate(objectsender,HtmlEventArgshe)

{

// ...});

JavaScript中调用Silverlight方法/属性

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

public partial classMainPage: UserControl{ publicMainPage() { InitializeComponent(); HtmlPage.RegisterScriptableObject("Page", this); } [ScriptableMember] public stringProcess(stringarg) { return"Called from js: "+arg;

}

}

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

functioncallSL() { varslHost = document.getElementById("SilverlightControl"); varpage = slHost.Content.Page;alert(page.Process('param from js'));}

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

点击运行结果如下:

Silverlight属性的调用方法同理。

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

JavaScript注册Silverlight中的事件

无参数事件

Silverlight中,事件用ScriptableMemberAttribute标记或者包含事件的类用ScriptableTypeAttribute标记后,再用HtmlPage.RegisterScriptableObject注册该类,在JavaScript中就可以访问该事件。比如Silverlight暴露如下事件:

public eventEventHandlerButtonClicked;

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

functiononSilverlightLoad() {varslHost = document.getElementById("SilverlightControl");varpage = slHost.Content.Page; page.ButtonClicked = function() { alert("Button clicked in SL."); };

}

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

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

带参数事件

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

事件参数类:

[ScriptableType]public classButtonClickedEventArgs: EventArgs{ public stringMessage { get; set; }}

MainPage类:

public partial classMainPage: UserControl{

private voidButton_Click(objectsender, System.Windows.RoutedEventArgse) {

// 引发ButtonClicked事件并传入事件参数 OnButtonClicked(newButtonClickedEventArgs() { Message ="Message from SL."}); } #region[ButtonClicked Event] [ScriptableMember] public eventEventHandlerButtonClicked; [System.Diagnostics.DebuggerStepThrough] protected virtual voidOnButtonClicked(ButtonClickedEventArgse) { 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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值