在我们正常创建的silverlight Application项目之后,会在相应的web文件夹中生成两个名称相同但扩展名分别为aspx和html和页面。
其中的aspx页面是我们所熟悉的控件声明方式的布局页,形如:
<
asp:ScriptManager
ID
="ScriptManager1"
runat
="server"
></
asp:ScriptManager
>
<
div
style
="height:100%;"
>
<
asp:Silverlight
ID
="Xaml1"
runat
="server"
Source
="~/ClientBin/**.xap"
MinimumVersion
="2.0.30523"
Width
="100%"
Height
="100%"
/>
</
div
>
在我之前所写的大部分silverlight文章中都是以这样的方面来声明并调用XAP文件的。但这种是采用控件声明方式来实现,而silverlight本身是可以在多种语言(包括动态语言)平台上开发,并跨浏览器运行的。比如我们就可以在html 中使用js来创建和操作silverlight对象(通过Silverlight.js提供),而相应的方法包括:
Silverlight.createObject
=
function
(source, parentElement, id, properties,
events, initParams, userContext)
Silverlight.createObjectEx
=
function
(params)
而在介绍这两个方法之前,有必要先看一下这张图:
上图中的
顺时针箭头方向表示当我们在HTM页面中采用JS方式创建SILVERLIGHT对象时,文件之间的相应调用关系。
当然本文为了简化这张图所调用的环节,直接将 CreateSilverlight.js 中的调用写在了htm中,将这不会影响我们对上图的理解。
好了,接下来先介绍上面提到的两个方法, 先说一下createObject,其函数声明如下(Silverlight.js文件中):
Silverlight.createObject
=
function
(source,
parentElement,
id,
properties,
events,
initParams,
userContext)
该方面中的参数说明摘自silverlight sdk:
source :对 XAML 内容的文件的引用,对应 Silverlight 插件的 Source 属性
parentElement: 对包含 createSilverlight 方法调用的 HTML 文件中块级元素的引用,在实例化后成为Silverlight 插件的宿主元素(也就是想在哪个元素中声明silverlight object)
id : HTML DOM 中对 实例化的 Silverlight 插件的唯一标识
properties :Silverlight 插件实例化属性的集合( width,height,background,isWindowless,frameRate,
inplaceInstallPrompt,version,ignoreBrowserVer,enableHtmlAccess)
events :能够在初始化时设置的 Silverlight 插件的事件集合
包括onError:当生成silverlight运行时组件报错信息的处理;
onLoad:当组件的onLoad事件触发时绑定的JS方法;
initParams : 初始化参数允许你指定用户定义的参数值。这些参数值可以在运行时通过访问插件的InitParams 属性得到。
userContext: 作为参数传给 OnLoad 事件处理器的唯一标识,可以被同一页面中的多个 Silverlight 插件共享。这个值唯一标识了哪个插件被加载,而无需检查 HTML DOM。更多信息请参见 使用 OnLoad 事件。
看着挺麻烦,但实际使用起来很简单,请看一下如下示例代码(对照上面的函数声明):
//
创建当前插件宿主元素(html)的引用.
var
parentElement
=
document.getElementById(
"
silverlightControlHost
"
);
//
对当前实例定义唯一标识变量.
var
conText
=
"
context_2
"
;
function
createSilverlightByPluginID(pluginID)
{
Silverlight.createObject(
"
ClientBin/Silverlight_Js.xap
"
,
//
源属性值.
parentElement,
//
Div标签宿主引用.
pluginID,
//
唯一插件ID值, 当页面调用被设置.
{
//
插件属性,此处属性设置优先于xaml中的设置
width:
'
400
'
,
height:
'
200
'
,
version:
'
2.0
'
,
isWindowless:
'
true
'
,
background:
'
aliceblue
'
,
framerate:
'
24
'
,
version:
'
2.0
'
},
{
onError:onSilverlightError,
//
错误处理事件绑定.
onLoad:onLoad
//
加载事件绑定,可用于多个实例.
},
"
pluginID=
"
+
pluginID,
//
初始化参数,可设置为 null 或 {}
conText);
}
这样我们就在"
silverlightControlHost"元素中定义了一个silverlight object对象。
当然上面JS代码中的onSilverlightError是在创建silverlight项目中就已声明好的,这里就不多做介绍了。需要说明的是onLoad的事件绑定,因为在这里我们可以对silverlight object做进行一步的操作如下:
/*
参数说明
plugin Object : 标识的 Silverlight plug-in 插件.
userContext String : 对象上面所说的userContext.
sender Object : 当前插件的根元素引用,如Canvas等
*/
function
onLoad(plugin, userContext, sender)
{
$get(
'
message
'
).innerHTML
=
plugin.id
+
"
:
"
+
userContext
+
"
:
"
+
sender.toString();
//
getHost()返回plug-in的引用
//
任何UIElement派生对象将可使用GetHost方法来返回Silverlight插件的实例.
var
plugin
=
sender.getHost();
//
获取初始化参数 InitParams 值,并使用逗号分割符分割该字符串.
var
params
=
plugin.initParams.split(
"
,
"
);
//
显示参数
var
msg
=
"
Params:
"
;
for
(
var
i
=
0
; i
<
params.length; i
++
)
{
msg
+=
params[i]
+
"
"
;
}
alert(msg);
//
只读属性 IsLoaded 是在 Onload 事件之前设置的,标识 Silverlight 插件是否已经加载。
alert(plugin.IsLoaded);
if
(plugin.IsVersionSupported(
"
2.0
"
))
{
alert(
"
当前版本支持 2.0
"
);
}
else
{
alert(
"
当前版本不支持 2.0
"
);
}
}
正如大家所看到了,我们可以通过getHost得到silverlight object属性中的一些重要信息,当然还可以进行版本检测,插件对象加载是否完成等功能的开发。不如要说明的是silverlight 版本号是按下面格式的字符串表示:
versionMajor.versionMinor.buildNumber.revisionNumber
看到这里,我们还需要再深入一步,看一下createObject方法体到底是执行了什么操作来进行对象声明的。
请看如下代码段(摘自silverlight.js):
Silverlight.createObject
=
function
(source,
parentElement,
id,
properties,
events,
initParams,
userContext)
{
var
slPluginHelper
=
new
Object();
var
slProperties
=
properties;
var
slEvents
=
events;
slPluginHelper.version
=
slProperties.version;
slProperties.source
=
source;
slPluginHelper.alt
=
slProperties.alt;
//
rename properties to their tag property names
if
( initParams )
slProperties.initParams
=
initParams;
if
( slProperties.isWindowless
&&
!
slProperties.windowless)
slProperties.windowless
=
slProperties.isWindowless;
if
( slProperties.framerate
&&
!
slProperties.maxFramerate)
slProperties.maxFramerate
=
slProperties.framerate;
if
( id
&&
!
slProperties.id)
slProperties.id
=
id;
//
remove elements which are not to be added to the instantiation tag
delete
slProperties.ignoreBrowserVer;
delete
slProperties.inplaceInstallPrompt;
delete
slProperties.version;
delete
slProperties.isWindowless;
delete
slProperties.framerate;
delete
slProperties.data;
delete
slProperties.src;
delete
slProperties.alt;
//
detect that the correct version of Silverlight is installed, else display install
if
(Silverlight.isInstalled(slPluginHelper.version))
{
//
move unknown events to the slProperties array
for
(
var
name
in
slEvents)
{
if
( slEvents[name])
{
if
( name
==
"
onLoad
"
&&
typeof
slEvents[name]
==
"
function
"
&&
slEvents[name].length
!=
1
)
{
var
onLoadHandler
=
slEvents[name];
slEvents[name]
=
function
(sender)
{
return
onLoadHandler(document.getElementById(id), userContext, sender)
};
}
//
绑定事件处理方法(有点C#事件绑定味道,呵呵)
var
handlerName
=
Silverlight.__getHandlerName(slEvents[name]);
if
( handlerName
!=
null
)
{
slProperties[name]
=
handlerName;
slEvents[name]
=
null
;
}
else
{
throw
"
typeof events.
"
+
name
+
"
must be 'function' or 'string'
"
;
}
}
}
slPluginHTML
=
Silverlight.buildHTML(slProperties);
}
//
The control could not be instantiated. Show the installation prompt
else
{
slPluginHTML
=
Silverlight.buildPromptHTML(slPluginHelper);
}
//
insert or return the HTML
if
(parentElement)
{
parentElement.innerHTML
=
slPluginHTML;
}
else
{
return
slPluginHTML;
}
}
//
/////////////////////////////////////////////////////////////////////////////
//
//
create HTML that instantiates the control
//
//
/////////////////////////////////////////////////////////////////////////////
Silverlight.buildHTML
=
function
( slProperties)
{
var
htmlBuilder
=
[];
htmlBuilder.push(
'
<object type=\"application/x-silverlight\" data="data:application/x-silverlight,"
'
);
if
( slProperties.id
!=
null
)
{
htmlBuilder.push(
'
id="
'
+
slProperties.id
+
'
"
'
);
}
if
( slProperties.width
!=
null
)
{
htmlBuilder.push(
'
width="
'
+
slProperties.width
+
'
"
'
);
}
if
( slProperties.height
!=
null
)
{
htmlBuilder.push(
'
height="
'
+
slProperties.height
+
'
"
'
);
}
htmlBuilder.push(
'
>
'
);
delete
slProperties.id;
delete
slProperties.width;
delete
slProperties.height;
for
(
var
name
in
slProperties)
{
if
(slProperties[name])
{
htmlBuilder.push(
'
<param name="
'
+
Silverlight.HtmlAttributeEncode(name)
+
'
" value="
'
+
Silverlight.HtmlAttributeEncode(slProperties[name])
+
'
" />
'
);
}
}
htmlBuilder.push(
'
<\/object>
'
);
return
htmlBuilder.join(
''
);
}
原来是用buildHTML方法将传入的属性按声明顺序组合成字符串并最终绑定到指定的
parentElement.innerHTML属性上,的确很简单,实在没什么可多说的了(当然里面的方法绑定略有不同,但与我们进行事件声明绑定有类似的语法味道)。
看到这里,还需要介绍一下另外一个创建对象的方法createObjectEx,其函数声明如下(silverlight.js中):
Silverlight.createObjectEx
=
function
(params)
{
var
parameters
=
params;
var
html
=
Silverlight.createObject(parameters.source, parameters.parentElement, parameters.id, parameters.properties, parameters.events, parameters.initParams, parameters.context);
if
(parameters.parentElement
==
null
)
{
return
html;
}
}
说白了它就是对createObject方法的一次封装(encapsulation),而这样做的目的就是为了让那些习惯使用JSON格式的程序员有一个感觉很舒服的参数声明方法,其最终的使用格式如下:
function
createSilverlightExByPluginID(pluginID)
{
Silverlight.createObjectEx({
source:
'
ClientBin/Silverlight_Js.xap
'
,
//
Source property value.
parentElement:parentElement2,
//
对包含 createSilverlight 方法调用的 HTML 文件中块级元素的引用,
//
在实例化后成为 Silverlight 插件的宿主元素
id:pluginID,
//
唯一的插件ID值
properties:{
//
插件属性.
width:
'
400
'
,
height:
'
200
'
,
inplaceInstallPrompt:
false
,
//
如果指定版本的 Silverlight 插件没有安装,inplaceInstallPrompt
//
初始化参数决定是否出现安装对话框。它的默认值是 false,也就是说,
//
如果 Silverlight.js 文件中版本检查返回 false,下面的 Silverlight
//
标准安装对话框将会出现。
background:
'
red
'
,
//
插件背景色
isWindowless:
'
true
'
,
//
是否在windowless 模式下显示插件.
framerate:
'
24
'
,
//
MaxFrameRate property value.
version:
'
2.0
'
},
//
Silverlight 版本.
events:{
onError:onSilverlightError,
onLoad:onLoad
},
initParams:
"
pluginID=
"
+
pluginID,
//
初始化参数
context:conText});
}
总体感觉与上面的createObject方法差别不是太大,但参数的可读性和层次性更清晰了。
到这里这两个重要的方法介绍的差不多了,下面的这个DEMO分别演示了这两种方法的使用方法。并通过指定不同的初始化
initParams方法来实现调用不同的XAML的功能(里面的CS代码很简单,大家下载之后一看便知)。
好的,今天的内容就先到这里了。
源码下载,请点击这里:)
Tag标签: silverlight, createObject, daizhj, 代震军