ASP.NET AJAX
Control
Toolkit中实现地最复杂的Extender估计就是AccordionExtender了。因为它对于DOM元素结构的要求比较高,所以它还为此实
现了AccordionPane控件,用来生成符合AccordionBehavior的DOM结构。但是在使用时,似乎总是会遇到一些限制,这里将对于
两个问题介绍一下简单的解决方案。
1、为AccordionExtender绑定DataTable
AccordinExtender支持数据
绑定,Toolkit的源码包内还附有TookitTests站点,其中对于AccordinBehavio的Test
Page展示了如何将XmlDataSource和数组绑定到AccordionExtender上,不过可能最常用的绑定还是DataTable(似乎
是,虽然我平时几乎都是将普通对象的列表用于绑定的)。奇怪的是AccordinExtender居然不支持DataTable的绑定,我简单地查看了代
码之后,发现它的数据绑定似乎只支持实现了IEnumerable接口的对象。不过这不要紧,还好DataRowCollection是实现了
IEnumerable接口的,我们可以把一个DataTable的Rows属性绑定到Accordin上。
下面是一个简单的示例,如下:
CSS Styles body { font-family : Verdana ; font-size : 10pt ; } .container { width : 300px ; } .header { height : 28px ; line-height : 28px ; color : white ; background-color : #2e4d7b ; border-bottom : solid 1px white ; width :100% ;} .header span { float : left ; margin-left : 10px ;} .header a { color :white ; float :right ; margin-right : 10px ; }
AccordinDataBinding.aspx < div class ="container" > < ajaxToolkit :Accordion ID ="MyAccordion" runat ="server" SelectedIndex ="0" HeaderCssClass ="header" FadeTransitions ="false" FramesPerSecond ="40" TransitionDuration ="250" AutoSize ="None" > < HeaderTemplate > < span > <% # this.GetColumnValue(Container.DataItem, "Title")%> </ span > < a href ="javascript:;" onclick ="" > toggle</ a > </ HeaderTemplate > < ContentTemplate > <% # this.GetColumnValue(Container.DataItem, "Description") %> </ ContentTemplate > </ ajaxToolkit :Accordion > </ div >
AccordinDataBinding.aspx.cs public partial class AccordionDataBinding : System.Web.UI.Page { private static DataTable dataTable = null ; static AccordionDataBinding() { dataTable = new DataTable(); dataTable.Columns.Add("Title ", typeof (string )); dataTable.Columns.Add("Description ", typeof (string )); dataTable.Rows.Add("Accordion ", "... "); dataTable.Rows.Add("Control or Extender ", "... "); dataTable.Rows.Add("What is ASP.NET AJAX? ", "... "); } protected void Page_Load(object sender, EventArgs e) { this .MyAccordion.DataSource = dataTable.Rows; this .MyAccordion.DataBind(); } protected string GetColumnValue(object row, string columnName) { return (row as DataRow)[columnName].ToString(); } }
我们将DataTable的Rows属性绑
定到Accordin之后,就相当于把每一个DataRow作为一个DataItem,于是在Code
Behind中实现了一个辅助用的GetColumnValue方法,可以方便地获取DataRow中某一列的值。于是绑定成功了,效果如下(伸缩中):
2、点击指定元素才产生伸缩效果
要解决这个问题我们先要来观察一下Accoridion的使用效果,当我们在Page中声明成如下时:
服务器端aspx页面代码 < ajaxToolkit :Accordion ID ="MyAccordion" runat ="server" HeaderCssClass ="HeaderCssClass" ContentCssClass ="ContentCssClass" > < HeaderTemplate > ...</ HeaderTemplate > < ContentTemplate > ...</ ContentTemplate > </ ajaxToolkit :Accordion >
它最后Render出的HTML如下:
Code < div id ="MyAccordion" > < span > <!-- 点击下面这个div会产生折叠的效果 --> < div > < div class ="HeaderCssClass" > ... <!-- Header内容 --> </ div > </ div > < div > < div class ="ContentCssClass" > ... <!-- Content内容 --> </ div > </ div > </ span > < span > ... </ span > ...</ div >
一般来说,用来存放Header的那个DIV会填满整个宽度,因此当点击Header的任意位置就会产生折叠效果。但是在某些情况下我们不会这样,我们会用户点击某个特定的控件,比如上例中的toggle链接时才进行折叠。我们现在就来解决这个问题。
首先,我们需要在用户点击Header时禁止click事件的触发。我们在这里使用一个略为复杂的HeaderTemplate,自定义了一个DIV用于填充整个Header空间,如下:
使用一个DIV覆盖整个Header空间 < ajaxToolkit :Accordion ID ="MyAccordion" runat ="server" SelectedIndex ="0" FadeTransitions ="false" FramesPerSecond ="40" TransitionDuration ="250" AutoSize ="None" > < HeaderTemplate > < div class ="header" onclick ="cancelToggle(event)" > < span > <% # this.GetColumnValue(Container.DataItem, "Title")%> </ span > < a href ="javascript:;" onclick ="toggle(this);" > toggle</ a > </ div > </ HeaderTemplate > < ContentTemplate > <% # this.GetColumnValue(Container.DataItem, "Description") %> </ ContentTemplate > </ ajaxToolkit :Accordion >
然后再那个DIV的onclick事件中终止事件向上级HTML元素继续传播,注意这里需要编写跨浏览器的代码,如下:
终止事件向上级HTML元素传播 function cancelToggle(e) { if (e.stopPropagation) { // FireFox e.stopPropagation(); } else { // IE e.cancelBubble = true ; } }
然后我们要做的就是在toggle链接被点击时,触发Accordin生成的Header元素的click事件。这里又涉及到跨浏览器的代码,其中FireFox略复杂一些,如下:
触发上级Header元素的click事件 function toggle(ele) { var header = ele.parentNode.parentNode.parentNode; if (header.click) { // IE header.click(); } else { // FireFox var e = document.createEvent("MouseEvents "); e.initEvent("click ", true , true ); header.dispatchEvent(e); } }
就此完成,这个解决方案还是非常简单的。至于使用效果,大家应该能够想象,也可以下载示例代码进行试验。
3、总结
当使用类库遇到问题时,我们可以尝试着查看类库的实现方式,或者做一下简单的常识,往往就可以得到解决方案。譬如无法绑定DataTable的问题,虽然古怪,但是我们只要换种方式,使用DataRowCollection进行绑定,还是可以得到相似的结果。
进行基于网页的开发时,要意识到浏览器只会
识别HTML,因此当我们在解决客户端的问题时,往往不用关心服务器端的实现,把眼光瞄准在对于客户端,使用“再普通不过”的HTML和
JavaScript进行扩展,往往就能够较好的完成任务。因此好的开发工具,特别是DOM查看器和JavaScript调试器会带来很大的帮助。当然,
对于HTML和JavaScript的了解越多,越能够快速地发现问题和解决问题。
4、示例文件下载
点击这里 下载示例文件。
本文出自 “赵劼 ” 博客,转载请与作者联系!
本文出自 51CTO.COM技术博客