因为Silverlight可以访问HTML中的DOM元素以及调用HTML页面中的JS方法,并且可以将自身的方法“暴露”
给HTML页面中的JS方法(通过[ScriptableMember]),所以我们可以利用这一特点来实现两个Silverlight应用
程序之间的数据通信。为了直观起见,本人做了这个DEMO,希望能够对大家在理解上有所帮助。
本DEMO的工作流程如下:
Silverlight 1 调用HTML中的JS方法,而该方法会去调用Silverlight 2中“暴露”的方法来显示选中的数
据。
请大家先看一下这个DEMO的运行效果,如下图所示:
在上图中分别有两个Silverlight应用,一个是雇员列表,一个是详细信息。其中的雇员列表是我以前在园
子里发表过的一遍文章中提到的DEMO,这里只是为了便于演示而简单的加以改造,其雇员类信息如下:
[ScriptableType]
public
class
EmployeeInfo
{
///
<summary>
///
雇员编号
///
</summary>
[ScriptableMember]
public
int
EmployeeNo {
get
;
set
; }
///
<summary>
///
雇员名称
///
</summary>
[ScriptableMember]
public
string
EmployeeName {
get
;
set
; }
///
<summary>
///
地址
///
</summary>
[ScriptableMember]
public
string
Address {
get
;
set
; }
}
上面的ScriptableType,ScriptableMember属性绑写是为了让html中的脚本代码可以访问(即可见)。
而下面的代码则是为了定义一个“脚本对象类”及其事件处理(包括参数)。
///
<summary>
///
雇员事件参数(用于完成与js绑定事件参数)
///
</summary>
[ScriptableType]
public
class
EmployeeInfoEventArgs : EventArgs
{
[ScriptableMember]
public
EmployeeInfo employeeInfo {
get
;
set
; }
}
///
<summary>
///
要注册并在页面中使用的js调用脚本对象
///
</summary>
[ScriptableType]
public
class
JavaScriptableObject
{
///
<summary>
///
js捆绑的事件处理器
///
</summary>
[ScriptableMember]
public
event
EventHandler
<
EmployeeInfoEventArgs
>
SelectEmployeeInfo;
public
void
OnSelectEmployeeInfo(EmployeeInfo employeeinfo)
{
if
(SelectEmployeeInfo
!=
null
)
{
SelectEmployeeInfo(
this
,
new
EmployeeInfoEventArgs()
{
employeeInfo
=
employeeinfo
});
}
}
}
接着就是一个雇员数据操作类,主要用于获取雇员信息,如下:
///
<summary>
///
雇员信息管理类
///
</summary>
public
class
EmployeeManager
{
public
IEnumerable
<
EmployeeInfo
>
employeeList;
///
<summary>
///
初始化会员数据
///
</summary>
public
EmployeeManager()
{
//
初始化雇员数据
employeeList
=
new
List
<
EmployeeInfo
>
()
{
new
EmployeeInfo(){EmployeeNo
=
10001
, EmployeeName
=
"
张三
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10002
, EmployeeName
=
"
李四
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10003
, EmployeeName
=
"
王五
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10004
, EmployeeName
=
"
马六
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10005
, EmployeeName
=
"
王大麻子
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10006
, EmployeeName
=
"
王宝强
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10007
, EmployeeName
=
"
王蛋蛋
"
, Address
=
"
北京
"
},
new
EmployeeInfo(){EmployeeNo
=
10008
, EmployeeName
=
"
王五强
"
, Address
=
"
北京
"
}
};
}
///
<summary>
///
获取指定数量的雇员数据
///
</summary>
///
<param name="count">
要获取的雇员信息数
</param>
///
<returns></returns>
public
IEnumerable
<
EmployeeInfo
>
GetEmployeeList(
int
count)
{
return
(from e
in
employeeList
select
new
EmployeeInfo
{
EmployeeNo
=
e.EmployeeNo,
EmployeeName
=
e.EmployeeName,
Address
=
e.Address
}).Take(count);
}
}
有了数据和数据结构,我们可以在应用程序中给列表控件绑定数据源了,如下:
//
这里必须声明是public,否则js调用该方法时会报错
[ScriptableMember]
public
void
LoadData(
int
count)
{
//
加载指定数据的雇员信息
EmployeeList.ItemsSource
=
new
EmployeeManager().GetEmployeeList(count);
}
当然DEMO中所提供的功能里有“选取某一行雇员信息”的操作,其实现方法如下:
///
<summary>
///
单击编辑雇员列表信息事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
EmployeeList_BeginningEdit(
object
sender, DataGridBeginningEditEventArgs e)
{
//
当有要编辑的信息时
if
(EmployeeList.SelectedItem
!=
null
)
{
EmployeeInfo employeeInfo
=
EmployeeList.SelectedItem
as
EmployeeInfo;
//
执行选中信息事件操作(最终会执行js所绑定的function代码)
javaScriptableObject.OnSelectEmployeeInfo(employeeInfo);
}
}
大家请注意上面的这一行代码:
javaScriptableObject.OnSelectEmployeeInfo(employeeInfo);
其完成的就是对HTML页面上JS绑定事件的调用,其JS绑写事件代码如下:
//
初始化操作
function
Init(obj) {
//
绑定js函数到silverlight的事件处理器
$get(
"
Xaml1
"
).content.EmployeeObject.SelectEmployeeInfo
=
ShowSelectEmployeeInfo;


}
当然,上面还有一个内容没有说明,即EmployeeObject对象是从哪来的,其实它就是我们公布到HTML中让
JS可以访问的对象JavaScriptableObject的实例,如下:
JavaScriptableObject javaScriptableObject;
void
Page_Loaded(
object
sender, RoutedEventArgs e)
{
javaScriptableObject
=
new
JavaScriptableObject();
//
注册js可用的类型(详情见Silverlight_JS_callTestPage.aspx中的js代码)
HtmlPage.RegisterScriptableObject(
"
EmployeeObject
"
, javaScriptableObject);
..
}
而JS方法"ShowSelectEmployeeInfo"即是实现对Silverlight 2应用中“暴露”方法的调用。其内容如下:
//
显示选取的雇员信息
function
ShowSelectEmployeeInfo(sender, args) {
$get(
"
Xaml2
"
).content.Page.LoadDetailData(parseInt(args.employeeInfo.EmployeeNo),
args.employeeInfo.EmployeeName,
args.employeeInfo.Address);
}
而Silverlight 2应用中的LoadDetailData方法所实现的就是将选中的单个雇员信息进行显示,如下:
//
这里必须声明是public,否则js调用该方法时会报错
[ScriptableMember]
public
void
LoadDetailData(
int
employeeNo,
string
employeeName,
string
address)
{
//
加载指定数据的雇员信息
EmployeeNo.Text
=
employeeNo.ToString();
EmployeeName.Text
=
employeeName;
Address.Text
=
address;
}
到这里,基本上DEMO中的主要内容就介绍完了。
下面再给大家演示一个Silverlight与FLASH进行数据通信 的例子,其实现的功能如下:
在Silverlight应用中拖动一张图片,在右侧的FLASH区域中相应的FLASH对象跟着被“移动”,其效果如下
图所示:
其实这个DEMO最初的原型出自微软件的黄继佳,我是在一次SILVERLIGHT培训中看到他这个演示,当时
我想实现原理应该与本文所提到的大同小异,后来被证实现确实如此。当然他的演示中实现的JS代码很简单,
完全就是用纯JS来实现即可。我这里并未完全使用了他的模型代码。因为上面所说的是在CS代码中进行事件的
绑定及其相关操作,所以我还是照上面所提供的思路重新写了这个DEMO,实现的效果与黄纪佳的原型基本相似。
因为篇幅起见,这里就不多做赘述了,大家下载代码后一看便知(SLImage.xaml.cs和SLtoFlash.htm文件)。
好的,今天的内容就先到这里了。
感兴趣的朋友可以在回复中进行讨论。
作者:代震军,daizhj
tags:silverlight, flash ,通信,数据传输
源码下载,请点击这里。