我们一起来学习如何把Silverlight 控件产生的事件抛给javascript并由javascript来处理。
基本原理: 就是在Silverlight中新建一个类,通过这个类来进行桥接,由它来把事件响应传递到Javascript,然后由Javascript来响应并处理Silverlight中的对应事件。
下面演示具体步骤:
我们新建一个Silverligth应用程序,命名为: SLJsHandleNetEvent
程序的结构图如下:
一、在Silverlight端添加一个类做为桥接,此类我们命名为: JsHandleEventObject。
它是本文内容的重点,与其配合,我们还将建立另外两个类,一个Student,一个是StudentsEventArgs,步骤如下:
1、添加一个类,命名为 Student,它有两个属性,一个是Name,一个是Age,它将作为事件传递的信息内容。其代码如下:
Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;//引入此命名空间
namespace SLJsHandleNetEvent
{
//自定义一个类Student,有两个属性,一个是Name,一个是Age
[ScriptableType]
public class Student
{
private string _name;
private float _age;
[ScriptableMember]
public string Name
{
get { return _name; }
set { _name = value; }
}
[ScriptableMember]
public float Age
{
get { return _age; }
set { _age = value; }
}
//构造函数
public Student()
{
this.Name = "NoName";
this.Age = 10;
}
//构造函数
public Student(string nameStr, float AgeFlt)
{
this.Name = nameStr;
this.Age = AgeFlt;
}
}
}
2、自定义一个EventArgs类,命名为 StudentsEventArgs,此类继承自 EventArgs基类,由它来承载 JsHandleEventObject 类中事件基本信息的传递,其内部定义了一个Student的数组,此数组将传递到Javascript进行获取和处理。此类代码如下:
Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;//引入此命名空间
namespace SLJsHandleNetEvent
{
//自定义包含数据事件的类,继承自EventArgs,用于传递事件的细节
[ScriptableType]
public class StudentsEventArgs:EventArgs
{
[ScriptableMember]
public Student[] Students { get; set; }
}
}
3、有了上面两个类做铺垫,下面我们就要建立桥接类 JsHandleEventObject,此类定义了一个名为 StudentsAvailable的事件,定义了一个激发此事件的方法 FireStudentsAvailable 。
Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;//引入此命名空间
namespace SLJsHandleNetEvent
{
//在这里,我们给JsHandleEventObject类添加了事件处理机制
//定义了事件StudentsAvailable
//定义了激发事件StudentsAvailable的方法FireStudentsAvailable
//此外我们还另行定义了事件
[ScriptableType]
public class JsHandleEventObject
{
[ScriptableMember]
public void FireStudentsAvailable(Student[] students) //定义了一个激发StudentsAvailable事件的方法FireStudentsAvailable
{
if (StudentsAvailable != null)
{
try
{
StudentsEventArgs sea = new StudentsEventArgs() { Students = students }; //初始化参数StudentsEventArgs
StudentsAvailable(this, sea); //激发事件StudentsAvailable,传入的参数有sender和StudentsEventArgs
}
catch(Exception ex)
{
string ke = ex.ToString();
}
}
}
[ScriptableMember]
public event EventHandler<StudentsEventArgs> StudentsAvailable; //定义了一个EventHandler类型的事件StudentsAvailable
}
}
二、建立Silverlight端的用户界面和相关事件
在此,我们创建一个Silverligth按钮,它有个Click事件,在此事件中,我们将利用上面创建的桥接类JsHandleEventObject来把此按钮的Click事件传递到Javascript进行捕获和处理。具体的工作包括:
1、注册 类JsHandleEventObject的一个对象实例,以实现在javascript中访问此对象实例,代码如下:
//
注册类JsHandleEventObject的一个对象实例,以实现在javascript中访问此对象实例
HtmlPage.RegisterScriptableObject(
"
MyScriptableObject
"
, myScriptableObject);
2、创建Student对象数组并初始化,它将做为事件信息进行传递。
Student[] st
=
new
Student[]
{
new
Student(
"
Jack
"
,
15
),
new
Student(
"
Tom
"
,
20
),
new
Student(
"
Simon
"
,
18
)
};
3、激发JsHandleEventObject类的FireStudentsAvailable事件,以便于在Javascript端进行捕获和处理。
myScriptableObject.FireStudentsAvailable(st);
//
激发JsHandleEventObject类实例的一个StudentsAvailable事件
//
并传入参数:一个Student类对象数组
Silverlight界面如图:
Silverlight界面代码如下(Page.xaml):
<
UserControl x:Class
=
"
SLJsHandleNetEvent.Page
"
xmlns
=
"
http://schemas.microsoft.com/winfx/2006/xaml/presentation
"
xmlns:x
=
"
http://schemas.microsoft.com/winfx/2006/xaml
"
Width
=
"
240
"
Height
=
"
100
"
>
<
Grid x:Name
=
"
LayoutRoot
"
Background
=
"
White
"
Width
=
"
240
"
Height
=
"
100
"
>
<
Button x:Name
=
"
btnClickInvoke
"
Width
=
"
200
"
Height
=
"
50
"
Content
=
"
请点击
"
FontSize
=
"
16
"
Foreground
=
"
Green
"
Margin
=
"
20
"
Click
=
"
btnClickInvoke_Click
"
></
Button
>
</
Grid
>
</
UserControl
>
Silverlight后台代码处理如下(Page.xaml.cs):
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;//引入此命名空间
namespace SLJsHandleNetEvent
{
public partial class Page : UserControl
{
JsHandleEventObject myScriptableObject = new JsHandleEventObject();
public Page()
{
InitializeComponent();
Loaded+=new RoutedEventHandler(Page_Loaded);
}
private void Page_Loaded(object sender,RoutedEventArgs e)
{
//注册类JsHandleEventObject的一个对象实例,以实现在javascript中访问此对象实例
HtmlPage.RegisterScriptableObject("MyScriptableObject", myScriptableObject);
}
//点击SL中的按钮控件,激发一个Click事件
private void btnClickInvoke_Click(object sender, RoutedEventArgs e)
{
Student[] st = new Student[]
{
new Student("Jack", 15),
new Student("Tom", 20),
new Student("Simon", 18)
};
myScriptableObject.FireStudentsAvailable(st);//激发JsHandleEventObject类实例的一个StudentsAvailable事件
//并传入参数:一个Student类对象数组
}
}
}
三、在Javascript端进行捕获和处理。
在此端我们需要做如下工作
1、在Javascript中获取桥接类对象JsHandleEventObjectbr
//
首先需要在javascript中取得类JsHandleEventObject的一个对象实例
var myXaml
=
$
get
(
"
Xaml1
"
);
var myContent
=
myXaml.content;
var myobject
=
myContent.MyScriptableObject;
2、编写自定义事件处理函数function OnStudentAvailable(sender, args),此函数我们将遍历由Silverlight端传递过来的事件信息 args(内含 Student数组信息),
并将它显示在一个div层中。当然,我们也可以对它做其它处理。
Code
//定义一个javascript函数OnStudentAvailable,此函数将响应在.NET代码中定义的
//类JsHandleEventObjec的StudentsAvailable事件
//此function有两个参数:
//一个是sender,用于传递JsHandleEventObjec对象实例
//一个是args,用于传递承载事件响应基本信息的StudentsEventArgs类实例(我们在.NET端赋予它的具体信息将通过它在javascript端进行获取)
function OnStudentAvailable(sender, args)
{
alert("事件被触发!");
//以下是创建一个表格来显示所取得的结果数据集
//结果数据集通过args参数传递进来
var sb = new Sys.StringBuilder();
sb.append("<table>");
sb.append("<tr>");
sb.append("运行结果如下表:");
sb.append("</tr>");
for (i = 0; i < args.Students.length; i++) //遍历args结果集,获取其承载的内部信息
{
sb.append("<tr>");
sb.append(String.format("<td width='200'>{0}</td>", args.Students[i].Name));
sb.append(String.format("<td width='100'>{0}</td>", args.Students[i].Age));
sb.append("</tr>");
}
sb.append("</table>");
//把结果集在div中显示出来
$get("results").innerHTML = sb.toString();
}
3、 把自定义事件处理函数OnStudentAvailable关联到类对象JsHandleEventObject的事件StudentsAvailable上。
也即:指派javascript function给.NET事件。在此处,我们是另添加一个按钮,点击后,它才完成指派功能,代码如下:
myobject.StudentsAvailable
=
OnStudentAvailable;
//
指派javascript function给.NET事件
程序界面如下:
SLJsHandleNetEventTestPage.aspx代码如下:
Code
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"
TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">
<head runat="server">
<title>SLJsHandleNetEvent</title>
<script type="text/javascript">
//定义一个javascript函数OnStudentAvailable,此函数将响应在.NET代码中定义的
//类JsHandleEventObjec的StudentsAvailable事件
//此function有两个参数:
//一个是sender,用于传递JsHandleEventObjec对象实例
//一个是args,用于传递承载事件响应基本信息的StudentsEventArgs类实例(我们在.NET端赋予它的具体信息将通过它在javascript端进行获取)
function OnStudentAvailable(sender, args)
{
alert("事件被触发!");
//以下是创建一个表格来显示所取得的结果数据集
//结果数据集通过args参数传递进来
var sb = new Sys.StringBuilder();
sb.append("<table>");
sb.append("<tr>");
sb.append("运行结果如下表:");
sb.append("</tr>");
for (i = 0; i < args.Students.length; i++) //遍历args结果集,获取其承载的内部信息
{
sb.append("<tr>");
sb.append(String.format("<td width='200'>{0}</td>", args.Students[i].Name));
sb.append(String.format("<td width='100'>{0}</td>", args.Students[i].Age));
sb.append("</tr>");
}
sb.append("</table>");
//把结果集在div中显示出来
$get("results").innerHTML = sb.toString();
}
function OnClick()
{
//首先需要在javascript中取得类JsHandleEventObject的一个对象实例
var myXaml = $get("Xaml1");
var myContent = myXaml.content;
var myobject = myContent.MyScriptableObject;
//然后把在Javascript端定义的事件处理函数(即上面定义的 function OnStudentAvailable(sender, args)
//指派到JsHandleEventObject对象实例的StudentsAvailable事件上
//也即:当我们在.NET代码中激发事件StudentsAvailable时,它将转而执行我们在此处为其指派的 function OnStudentAvailable(sender, args)
//从而实现在Javascript中处理.NET 事件的目的
myobject.StudentsAvailable = OnStudentAvailable; //指派javascript function给.NET事件
alert("成功注册!请点击Silverlight按钮激发事件");
}
</script>
</head>
<body style="height:100%;margin:0;">
<form id="form1" runat="server" style="height:100%;">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div style="height:100%;">
<asp:Panel ID="Panel1" runat="server">
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SLJsHandleNetEvent.xap" MinimumVersion="2.0.31005.0" Width="400" Height="200" />
<br />
<input type="button" value="注册Javascript事件处理函数" onclick="OnClick()" />
<div id="results"></div>
</asp:Panel>
</div>
</form>
</body>
</html>
运行效果如图(先点击"注册Javascript事件处理函数"按钮,再点击Silverligth按钮):
前往:Silverlight学习笔记清单
本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)