简单探照灯遮照效果的几个Silverlight程序(Silverlight 2.0)

简单探照灯遮照效果的几个Silverlight程序(Silverlight 2.0),第1张

概述最近做SonySource项目时实现了几个很小的Silverlight程序,分别是Clock、HomePeoplePicker和ManageMentPeoplePicker。实际上这三个silverlight程序都非常简单,主要特点有以下几个方面:   1. Silverlight程序和页面上的HTML元素混合在一起,且在特定事件触发后要动态改变Silverlight程序在页面中占的位置及大小,但

最近做SonySource项目时实现了几个很小的Silverlight程序,分别是Clock、HomePeoplePicker和ManageMentPeoplePicker。实际上这三个silverlight程序都非常简单,主要特点有以下几个方面:

  1. Silverlight程序和页面上的HTML元素混合在一起,且在特定事件触发后要动态改变Silverlight程序在页面中占的位置及大小,但给用户的感觉是无缝连接;
  2. JavaScript和Silverlight相互调用;
  3. 简单的探照灯遮照效果

      下面就分别对我认为比较不好处理的地方或者一些我费了很多周折才实现的地方做一简要说明:

一、使Silverlight浮动在HTML元素中,并动态改变大小

  或许我这个小标题描述得还不是很准确,不能直观表达我的意思。举个例子,假设我们要用Silverlight做个下拉菜单,并将他放在HTML页面上使用。我们希望这个silverlight菜单所占的大小只是980px宽和30px高,因为在紧挨菜单的上面和下面的地方我们要放置一起其他的HTML元素。但当用户点击某个菜单项时,这个子菜单就展开,假设子菜单的大小是100px款和200px高,那就要求Siverlight所占的位置至少高为230px。由于Silverlight菜单只有30px高,所以下拉菜单就被截断而不能完整显示。我做的这个项目里三个Silverlight都遇到类似问题。例如PeoplePicker是在一个表格框里显示很多人的图像,当用户点击一个人的图像的时候d出一个窗口以显示人的详细信息,在某种情况下,这个d出窗口会超出包含所有人物图像的表格从而部分被截断。在《Silverlight嵌入到HTML之windowless属性及运用AjaxControlToolKit时出现虚线边框的问题》所描述的问题就是基于这种需求。

  上述问题是否可以简单的描述为:Silverlight程序在页面上只在指定的Silverlight plug in(<object/>元素)中显示,当超过Silverlight Plug in时就会被截除;当Silverlight程序的宽和高在运行时不确定时,就要求Silverlight Plug in的大小和位置随之改变以使所有silverlight内容都能完整正确的显示出来。

      我在这个项目里的解决办法就是基于以上的描述,动态改变Silverlight plug in(object元素)的大小,并时silverlight plug in以绝对定位的方式浮动于其他元素之上,且让silverlight plug in的背景色为透明以不至于让他遮盖所有的底层元素。

  首先,我们在页面上定义一个<div>元素,我们的silverlight程序就放在这个<div>里,并以它作为silverlight的定位基准。即正常情况下silverlight和包含它的<div>的位置和大小完全一致。当需要改变silverlight的大小和位置时,也以该<div>为参考。在页面布局时,我们只用关注这个<div>应该放到哪就行了。HTML代码大致如下:

   那么怎么初始化silverlight的位置和大小呢?就在onload事件里处理: 

 在onSilverlightHomePeoplePickerLoaded事件中,首先通过参数sender创建一个SilverlightHomePeoplePicker的实例,SilverlightHomePeoplePicker对象的代码大致如下:

 可以看到,在构造SilverlightHomePeoplePicker的实例时就设置了<object/>元素的位置和大小。

  leftOffsetToContainer和topOffsetToContainer是指silverlight plug in ( object 元素 )左上相对于包含它的<div>的左上角的偏移量,一般正常情况下,这个偏移量为0,即silverlight与包含它的<div>左上角位置重叠。初始化时同时设置了silveright插件的宽和高,即等于包含它的<div>的宽和高。

  那么当Silverlight的位置和大小需要改变时怎么办呢?谁来负责处理这个变化呢?首先,在Silverlight程序里应该最先知道这个Silverlight程序的范围是否改变了,是否需要改变silverlight plug in的位置和大小来正确显示整个Silverlight的内容。例如,当d出或关闭详细信息窗口时,Silverlight程序应该做这个检查,如果需要改变silverlight plugin的位置和大小,就通知JavaScript程序。

  Silverlight的启动xmal文件Page.xaml大概是这个样子:

然后定义一个SilverlightScopeChangeHandler:

在Page.cs页面中,当捕获到需要改变silverlight plugin(object元素)的位置和大小时,就触发相应的SilverlightScopeChange事件:

 当Silverlight应用程序检查到需要改变<object>元素的大小时,就触发SilverlightScopeChanged事件,告知JavaScript来处理,同时SilverlightScopeChangeEventArgs参数还告诉了silverlight plug in需要的宽、高以及相对于上级<div>的偏移量。

  到这里,大家就会看到上述SilverlightHomePeoplePicker代码中
  this.page.addEventListener("SilverlightScopeChanged", SilverlightHomePeoplePicker.createDelegate(thisthis.handleSilverlightScopeChangedEvent));
的意义所在了。
二、Silverlight程序和JavaScript程序的相互调用 

  1. JavaScript注册silverlight的事件

  其实上面的代码已经体现了这点,即通过JavaScript的代码
  this.page.addEventListener("SilverlightScopeChanged"this.handleSilverlightScopeChangedEvent));
来注册silverlight端的事件。这里要注意几点:
     a. Silverlight事件必须是Scriptable的,即事件的声明上加上[ScriptableMember];
     b. 事件原型必须有两个参数,sender和e。sender是object类型的,e需要时继承自EventArgs类型的。我在这里走了些弯路。
              c. 必须在Silverlight程序中注册整个类以供JavaScript访问,例如:HTMLPage.RegisterScriptableObject("Page",this);
     d. silverlight程序在LayoutUpdated事件中是无法访问或触发任何JavaScript方法的。

  2. silverlight注册HTML element的事件
    在silverlight中可以注册HTML元素的事件。例如在clock程序中,要求当用户点击网页上任何位置时都要关闭timezoneList下拉列表。这时可以在silverligh中注册document.click事件:


 

 但后来由于firefox下点击silverlight时也触发document.click事件,所以没有采用这种方式。

  3. JavaScript调用Silverlight的方法9
   由于没有采用第2点所示的方法,所以document.click事件还是由JavaScript来处理:
   但是,在handleClickdocumentEvent事件里,JavaScript调用了silverlight的方法:
  this.page.HIDeTimezoneList();
  与第1条所述类似,silverlight中HIDeTimezoneList这个方法必须标记为[ScriptableMember],且要注册Page类到Js:
  HTMLPage.RegisterScriptableObject("Page",this);  

三、简单探照灯效果的实现

   这里的探照灯的实现,主要运用了RadialGradIEntBrush。在整个Silverlight的内容上面放一个Rectangle,且将其Fill为RadialGradIEntBrush:

 当鼠标移动时,就动态改变RadialGradIEntBrush的Center和GradIEntOrigin属性。大致代码如下: 

另外还有一个问题,由于在所有内容上遮照了一个Rectangle,那么当鼠标移到某个位置时,虽然灯亮了,那怎么触发Rectangle下层元素的事件呢?我这里主要运用了包含Rectangle的Canvas的Clip属性,在Clip里我定义了两个Geometry,动态改变Geometry的位置,就相当于在Rectangle上动态打一些窟窿。

四、其他问题 

  当然还有一些需要改进的地方,例如Clock的点"edit"按钮后d出的下拉框的宽和高应该动态自适应,可以在TimezoneList的Curstom Control的MeasureOverrIDe事件中获取应该分配的宽和高,进而计算其他数据达到自适应的效果,简单伪代码如下:

    还有,在探照灯已经固定在某一个人的头像上后,当鼠标滑动时还可以使效果更加柔和。

 

五、程序效果演示

HomePeoplePicker

ManagementPeoplePicker

Clock

总结

以上是内存溢出为你收集整理的简单探照灯遮照效果的几个Silverlight程序(Silverlight 2.0)全部内容,希望文章能够帮你解决简单探照灯遮照效果的几个Silverlight程序(Silverlight 2.0)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1050849.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存