一个我在研究Atlas Control Toolkit时做的尝试:ImageGalleryExtender

  ImageGalleryExtender是我在研究Atlas Control Toolkit代码时的一个尝试。这个Extender的作用是能够轻松地制作一个相册浏览的功能。

制作这个的起因是因为昨天在http://www.flickr.com/上看图片时,被它的Slidershow浏览方式所吸引,它是用Flash实现的。最近一直在研究Atlas和Atlas Control Toolkit的实现和基础代码,因此决定开发一个Extender,暂且命名为ImageGalleryExtender。它基于9/14最新的Release开发。

制作这个Extender基本上没有遇到什么麻烦,只是按部就班的完成。基本上花在客户端脚本编程的时间大约为服务器端的两倍。我认为,一个Extender其实只是一个被封装完整容易发布和部署的一个控件,在客户端编程方面,Atlas除了提供了一些辅助方法之外,并没有对于开发上有比较明显的帮助。在服务器端只是普通的控件,大多数情况只需定义一些属性即可。当然如果需要更强大的功能,自然需要加大功夫,比如需要像Accordion般定义Template等。当然这些都控制在控件的范围内,对于控件开发经验丰富的朋友应该不会造成什么困扰。顺便提一下,我打算在后面一段时间内写一系列文章,将我研究Atlas和Atlas Control Tookit基础代码实现的一些心得体会写下来,这样可以帮助更多的朋友们解决开发和使用时遇到的问题。毕竟靠阅读代码,甚至依靠反编译类库所了解到的,与从文档资料上获得的信息要来得具体和透彻。例如我在开发ImageGalleryExtender时,就使用了文档上没有记载的方法,重载Extender的一个函数将一个服务器端的一个Collection输出到了客户端Behavior的一个属性上。其实Atlas Control Toolkit里提供用来开发Extender的基类有许多可以重载的方法,了解它们的作用并灵活地使用使用它们,能够大幅提高我们开发Extender的效率。即时遇到了问题,也能很快地找到解决方法或者Work around。

ImageGalleryExtender的代码可以在这里下载到,感兴趣的朋友们可以下载下来一看。因为我只是比较简单地实现了这个Extender,花的时间也不长,也没有相当认真地去考究代码质量,所以就先不做代码解析了。自然,我随时欢迎朋友们和我讨论和交流开发经验。另外提一下,不仅限于Atlas。:)

先从使用方式说起吧。和普通的Extender一样,只需引入一个程序集即可。在使用ImageGallery时,只需将压缩包内的ImageGallery Project引入到WebSite所在的Solution内,然后为WebSite添加引用,然后编译即可。当然,也可以编译好ImageGallery Project以后将ImageGallery.dll引入WebSite Project。至于使用方式,就从我写的演示网页看起吧。页面代码如下:
29174913_FCm8.gif 29174914_Y7Vy.gif  ImageGalleryExtender Sample Code
  129174914_Y7Vy.gif29174913_FCm8.gif<%29174914_QXSB.gif@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
  229174914_Y7Vy.gif29174913_FCm8.gif<%29174914_QXSB.gif@ Register Assembly="ImageGallery" Namespace="Jeffz.AtlasControlToolkit" TagPrefix="jeffz" %>
  329174914_luSt.gif
  429174914_luSt.gif<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  529174914_luSt.gif<html xmlns="http://www.w3.org/1999/xhtml">
  629174914_luSt.gif<head runat="server">
  729174914_luSt.gif    <title>Image Gallery Extender Sample</title>
  829174914_Y7Vy.gif29174913_FCm8.gif    <script language="javascript">29174914_QXSB.gif
  929174914_Ykwz.gif        var imageGallery = null;
 1029174914_Ykwz.gif    
 1129174914_Ykwz.gif        function init()
 1229174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 1329174914_Ykwz.gif            imageGallery = $("<%= this.Panel1.ClientID %>").control;
 1429174914_Ykwz.gif            next();
 1529174914_qEkV.gif        }
 1629174914_Ykwz.gif        
 1729174914_Ykwz.gif        function next()
 1829174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 1929174914_Ykwz.gif            if (imageGallery)
 2029174914_W60T.gif29174914_a0SZ.gif            29174914_QXSB.gif{
 2129174914_Ykwz.gif                imageGallery.next();
 2229174914_qEkV.gif            }
 2329174914_qEkV.gif        }
 2429174914_Ykwz.gif        
 2529174914_Ykwz.gif        function previous()
 2629174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 2729174914_Ykwz.gif            if (imageGallery)
 2829174914_W60T.gif29174914_a0SZ.gif            29174914_QXSB.gif{
 2929174914_Ykwz.gif                imageGallery.previous();
 3029174914_qEkV.gif            }
 3129174914_qEkV.gif        }
 3229174914_Ykwz.gif        
 3329174914_Ykwz.gif        function selectIndex()
 3429174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 3529174914_Ykwz.gif            if (imageGallery)
 3629174914_W60T.gif29174914_a0SZ.gif            29174914_QXSB.gif{
 3729174914_Ykwz.gif                var index = parseInt(document.getElementById("imageIndex").value, 10);
 3829174914_Ykwz.gif                imageGallery.select(index);
 3929174914_qEkV.gif            }
 4029174914_qEkV.gif        }
 4129174914_Ykwz.gif        
 4229174914_Ykwz.gif        function resizePanel()
 4329174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 4429174914_Ykwz.gif            if (imageGallery)
 4529174914_W60T.gif29174914_a0SZ.gif            29174914_QXSB.gif{
 4629174914_Ykwz.gif                imageGallery.element.style.width = parseInt(document.getElementById("panelWidth").value, 10+ "px";
 4729174914_Ykwz.gif                imageGallery.element.style.height = parseInt(document.getElementById("panelHeight").value, 10+ "px";
 4829174914_Ykwz.gif                imageGallery.adjustImage();
 4929174914_qEkV.gif            }
 5029174914_qEkV.gif        }
 5129174914_Ykwz.gif        
 5229174914_Ykwz.gif        function setInterval()
 5329174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 5429174914_Ykwz.gif            if (imageGallery)
 5529174914_W60T.gif29174914_a0SZ.gif            29174914_QXSB.gif{
 5629174914_Ykwz.gif                var interval = parseInt(document.getElementById("interval").value, 10);
 5729174914_Ykwz.gif                imageGallery.set_Interval(interval);
 5829174914_qEkV.gif            }
 5929174914_qEkV.gif        }
 6029174914_Ykwz.gif        
 6129174914_Ykwz.gif        function setSwitchTime()
 6229174914_W60T.gif29174914_a0SZ.gif        29174914_QXSB.gif{
 6329174914_Ykwz.gif            if (imageGallery)
 6429174914_W60T.gif29174914_a0SZ.gif            29174914_QXSB.gif{
 6529174914_Ykwz.gif                var time = parseInt(document.getElementById("switchTime").value, 10);
 6629174914_Ykwz.gif                imageGallery.set_SwitchTime(time);
 6729174914_qEkV.gif            }
 6829174914_qEkV.gif        }
 6929174914_udTO.gif    </script>
 7029174914_luSt.gif</head>
 7129174914_luSt.gif<body style="font-family: Arial; font-size: 12px;">
 7229174914_luSt.gif    <form id="form1" runat="server">
 7329174914_luSt.gif        <atlas:ScriptManager ID="ScriptManager1" runat="server" EnableScriptComponents="true"/>
 7429174914_luSt.gif        
 7529174914_luSt.gif        <jeffz:ImageGalleryExtender runat="server" ID="ImageGalleryExtender1">
 7629174914_luSt.gif            <jeffz:ImageGalleryProperties TargetControlID="Panel1" WaitingControlID="WaitControl" Interval="5" SwitchTime="2">
 7729174914_luSt.gif                <Images>
 7829174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdv-J-j6tzA0gHGu1lA1RYmFGOARKhSDDszRmKZtbShSMju6x3BhtZ0mrq9njA_mz2FJCLfVQUoMARFjTolWjm9zRvHBwzCnErwOM-V0qmI0L0L1J2fR8Pyw" />
 7929174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdjQFyIVvds_BLrgJ5cwuW_j7wkE0RZPb2yfzlNXAqszE3mJ4r6O0ezSldAxu6RlpSuBx_KEsMLF5WMSliE1BMzJJ1i0QFaiCwuEANPJ3VqEXfSXUC4mJvuA" />
 8029174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdmjcmjrzY7XqcJoJ-Bz5EmdaMc28KwFZ3ilvvuNWnOikIlm0dc7lo37N1hYMOB_8jxwyNAgg8xW4VdxA8VuxupoqsdIw9XjYB-pNZf8bHIuDHkNVn1KVDpc" />
 8129174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdjEdK6jQabmw3M9k9CUKlxCaEo6mmu6T7TTg6j4LSfq3hJ34nZPIk0YjrrA20tt-3iJSlvS8fA7KXi7Skp5T19wokR8vzua7ZYtUz90iaCIs_AoBqW3tr4U" />
 8229174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdghsNNH78e3sWjkGpFUxmVBvF_d4jPnld60IFknNUfQ7lomfts0KIFFzcoEFei3b6GNjKC68F6tZ26ZjW0MNllGaRgkqj4t9ylN194hvf-GVc9jvjAmv9tY" />
 8329174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdmmTHSa6M61PwCDwNulEaQOvQX9uuhN5c3ZECK97k-D5LfZKxcKhcDs4bGrwjZzgCg5Ub8vVKoTnjCsFbXIbhqGVjFl9xkynhxfBIgStFzrE" />
 8429174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIds5l2PGCRUFwqHpweODQhmVhKdyXte2b36rw4CMWTa2a_9im9YV3b3I2V-d4UhVNmIqoiwy_iCWTOpxeT4Nfd5iw3utazAOJz_325qeYz-l1dOsSgDIhXVg" />
 8529174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIdmjcmjrzY7Xq8ke3QWFFATfl0Yn-RxXbCLxIQYdV4Gr-FIVJZNDHHnYRYFaLXoZYABI6sRV8jpQBeKZq3-mVKLNiZDfHY6BYWWJlTGhmnCFTu_rxAAorfQE" />
 8629174914_luSt.gif                    <jeffz:Image Url="http://tkfiles.storage.msn.com/x1pNWjjkHJ3o_z6MhmqM-UIds5l2PGCRUFwgonXruB9imxg4NJ4U8hCWoaBpSb0o3nXB3vDgxT2TIIFwAwl1R8jk1czq9TgYEdcK6F0AWMi454KmXNw7vBeF_X9A7yEQwWB-SQ1M0PwI4c" />
 8729174914_luSt.gif                </Images>
 8829174914_luSt.gif            </jeffz:ImageGalleryProperties>
 8929174914_luSt.gif        </jeffz:ImageGalleryExtender>
 9029174914_luSt.gif
 9129174914_luSt.gif        <div>
 9229174914_luSt.gif            <href="javascript:previous();">&lt;&lt;</a>
 9329174914_luSt.gif            &nbsp;&nbsp;&nbsp;&nbsp;
 9429174914_luSt.gif            <href="javascript:next();">&gt;&gt;</a>
 9529174914_luSt.gif            <hr />
 9629174914_luSt.gif            <div>
 9729174914_luSt.gif                <input type="text" value="0" id="imageIndex" />
 9829174914_luSt.gif                <input type="button" value="Select Index" onclick="javascript:selectIndex();" />
 9929174914_luSt.gif            </div>
10029174914_luSt.gif            <hr />
10129174914_luSt.gif            <div>
10229174914_luSt.gif                Width:<input type="text" value="600" id="panelWidth" /><br />
10329174914_luSt.gif                Height:<input type="text" value="700" id="panelHeight" /><br />
10429174914_luSt.gif                <input type="button" value="Resize Panel" onclick="javascript:resizePanel();" />
10529174914_luSt.gif            </div>
10629174914_luSt.gif            <hr />
10729174914_luSt.gif            <div>
10829174914_luSt.gif                <input type="text" value="0" id="interval" />
10929174914_luSt.gif                <input type="button" value="Set Interval" onclick="javascript:setInterval();" />
11029174914_luSt.gif            </div>
11129174914_luSt.gif            <hr />
11229174914_luSt.gif            <div>
11329174914_luSt.gif                <input type="text" value="0" id="switchTime" />
11429174914_luSt.gif                <input type="button" value="Set Switch Time" onclick="javascript:setSwitchTime();" />
11529174914_luSt.gif            </div>
11629174914_luSt.gif        </div>
11729174914_luSt.gif        
11829174914_luSt.gif        <asp:Panel ID="Panel1" runat="server" Height="700px" style="position: relative;" Width="600px" BackColor="#EEEEEE">
11929174914_luSt.gif            <span style="color:Red;" ID="WaitControl" runat="server">Loading</span>
12029174914_luSt.gif        </asp:Panel>
12129174914_luSt.gif    </form>
12229174914_luSt.gif
12329174914_Y7Vy.gif29174913_FCm8.gif    <script type="text/xml-script">29174914_QXSB.gif
12429174914_Ykwz.gif        <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
12529174914_Ykwz.gif            <references>
12629174914_Ykwz.gif            </references>
12729174914_Ykwz.gif            <components>
12829174914_Ykwz.gif                <application load="init" />
12929174914_Ykwz.gif            </components>
13029174914_Ykwz.gif        </page>
13129174914_udTO.gif    </script>
13229174914_luSt.gif</body>
13329174914_luSt.gif</html>

在使用ImageGalleryExtender时,需要将一个Panel作为Target Control传递给一个ImageGalleryProperties,然后将任意一个控件作为Waiting Control通过WaitingControlID传递给ImageGalleryProperties。作为Target Control的Panel会作为容器来显示页面。而Waiting Control会被作为提示用户正在加载图片的控件。Image Gallery会在适当的时候将该对象的Visibility Style在Visible和Hidden之间切换。虽然有提示信息,但是Image Gallery会在后台加载用户没有查看的图片,目的是省去了以后用户切换到那幅图片时所需的加载时间。

需要注意,作为Target Control的Panel,其style.position属性需要设为relative或者absolute。因为其中的图片是以绝对定位的方式出现。由于用户可能会灵活地改动这个值,因此这方面就交由用户自己来保证了。

ImageGalleryProperties还有另外两个属性,Interval和SwitchTime。Interval的作用是设置自动切换图片所需等待的间隔时间,单位是秒。如果赋予了0或者负数,那么Image Gallery不会自动切换图片。SwitchTime的作用是设置切换图片时淡入/淡出效果所需要的时间。比如就例子而言,在一张图片显示完整后,将等待5秒将进行图片转换,转换时会有淡入/淡出效果,效果时间为2秒。然后接着等待5秒以后,又将切换至下一张图片。

一个ImageGalleryProperties还会有一个类型为ImageCollection的属性Images,里面存放的是需要在Image Gallery里显示的图片信息。在Editor中会有提示信息,很容易编辑。每个Image对象会有三个属性:“Url”,“Width”和“Height”,三者的含义自不必说。其中要注意的是,我在Url中并没有像ASP.NET中服务器控件一样提供对于“~”的支持。Width和Height的单位是像素,当然在编辑时输入的是整数。

我把Width和Height使用.NET 2.0中Nullable Value - “int?”的方式提供。如果没有对这两个属性赋值,那么他们的值默认是null。用户可以不提供任何一个,即使用图片的默认大小来显示。如果用户同时提供了Width和Height属性,那么图片会以用户希望的方式显示。如果用户只提供了其中一个,那么图片的大小会根据用户提供的Width或Height,结合那幅图片的长宽比,计算出另一个属性的值。自然,这项功能是在客户端保证的。另外,由于作为Image Gallery Container的那个Panel有大小限制,因此图片在显示时也会根据Panel的大小有所调整:如果Panel足够大,那么图片会以横向纵向都居中的方式显示。如果Panel的大小使得图片无法以完整大小显示(即根据用户指定的Width和Height值,结合图片原有的大小得到的尺寸),那么图片会在保证长宽比不变的前提下尽可能的显示大图片。这点在演示中均可以看到效果。

当然,一般来说,不会以在页面里直接写代码的方式来指定一个Image Gallery里会显示哪写图片。事实上,也可能在代码里添加图片信息。例如在演示网页中,就可以写入类似这样的代码:
1 29174914_luSt.gif protected   void  Page_Load( object  sender, EventArgs e)
2 29174914_Y7Vy.gif29174913_FCm8.gif 29174914_QXSB.gif {
329174914_Ykwz.gif    this.ImageGalleryExtender1.TargetProperties[0].Images.Add(new Image("Url"nullnull));
429174914_udTO.gif}

为了方便客户端功能,我为客户端的控件对象(注意不是Html Element)提供了一些属性和方法,它们可以像演示网页中那样通过$("PanelClientID").control.XXXXX访问到。下面我一一说明控件对象中可以使用的方法:

function next(): 切换至下一副图片。初始化完ImageGalleryBehavior后Image Gallery不会马上开始,需要通过主动调用next函数启动。
function previous(): 切换至前一幅图片。
function select(index):切换至下标为index的那幅图片。如果选择的index正是当前的图片,那么则不会有任何效果。如果index不在0到Images.Count - 1之间,那么会将其进行取模运算,以保证参数的合法性。不过还是强烈推荐将正确的参数传递给该函数。
function adjustImage():用于调整图片的大小与位置。由于图片采用了绝对定位,因此如果Container的大小有所改变时,图片就不能以正确的尺寸和位置显示了。这时候就需要调用控件对象上的adjustImage函数,它会根据Container的当前尺寸来调整图片尺寸和位置。一般来说,这个方法会在resize事件中被调用。
RW属性SwitchTime:用于读取和设置图片淡入/淡出所需的时间。
RW属性Interval:用于读取和设置切换两张图片之间的间隔。

最后再说一下演示页面的使用, 点击这里可以访问到ImageGalleryExtender的演示页面。具体代码非常的简单,下面是演示页面功能以及效果:

29174914_Y8Fz.jpg

事实上目前的ImageGalleryExtender还有一些需要改进的地方。例如目前如果显示了无法加载的图片,那么Gallery的操作则会停止并无法启动。我会一点点改进这个控件,解决这些问题。

ImageGalleryExtender能够在IE和FireFox下正确运行。

转载于:https://my.oschina.net/abcijkxyz/blog/721524

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值