使用createObject(createObjectEx)创建silverlight对象

简介:
    在我们正常创建的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代码很简单,大家下载之后一看便知)。

       
 
     好的,今天的内容就先到这里了。


本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/86144,如需转载请自行联系原作者
相关文章
Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象
原文:Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象 原创文章,如需转载,请注明出处。   最近在一直研究Silverlight下的数据绑定控件,发现有这样两个接口IEditableObject 和IEditableCollectionView,记录一下结论,欢迎交流指正。
870 0
Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效
原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效   当我们在进行Silverlight & Blend进行动画设计的过程中,可能需要设计出很多效果不一的图形图像出来作为动画的基本组成元素。
1050 0

热门文章

最新文章