當ASP.NET框架要求WEB控件保存數據到視圖中,系統會自動調用控件的SaveVIEwState函數,當ASP.Net框架要求WEB控件從數據視圖中加載數據時,系統會自動調用WEB控件的LoasVIEwState函數。能保存在數據視圖中的對象必須能進行二進制序列化。這就是在 SkyTreeNode和SkyTreeNodeList類型前面都附加聲明類型能進行二進制序列化的 “[System.Serializable()]”的原因。
分析SkyTreeVIEwControl的源代碼,讀者可以看到這個WEB控件還是比較復雜的,它需要了解ASP.Net自定義控件的一些知識,此外還需要掌握Javascript和IE浏覽器XML數據島的知識。
XML數據島是IE浏覽器特有的功能,是微軟對HTML標准的擴展,其他浏覽器是不支持XML數據島的,實際上我們可以使用 XMLHttpRequest 的ActiveX組件來從服務器上下載XML文檔,而FireFox是支持XMLHttpRequest的,這樣可以做到對Firefox的兼容。在這裡我特地演示使用了XML數據島的功能,而且使用XML數據島的功能能將XML文檔嵌入到Html文檔中,減少WEB系統的文件數,從而降低系統復雜度,而且方便部署。若規定客戶端浏覽器限制為IE浏覽器時,則可以采用XML數據島的功能。
SkyTreeVIEwControl.xslt
這個WEB控件中有一個很重要的文檔就是XSLT模板文檔。它保存在文件SkyTreeVIEwControl.xslt中,並作為嵌入的資源參與程序的編譯。這個XSLT模板文檔的主體結構為
<?XML version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet XMLns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--
和 SkyTreeVIEwControl 樹狀列表控件配合使用的XSLT文檔,本文檔的生成操作必須為“嵌入的資源”。
編制 袁永福 2008-1-29
-->
<xsl:output method="Html" indent="no" />
<!-- ***************** 主模板,為XSLT轉換的入口點 ******************** -->
<xsl:template match="/*">
------------- 主模板的內容 -----------------------
</xsl:template>
<!-- ******************* 輸出一個樹狀列表節點 *************************** -->
<xsl:template name="TreeNode">
-------------- 子模板的內容 ----------------------
</xsl:template>
< /xsl:stylesheet>
這裡使用了xsl:output指令
<xsl:output method="Html" indent="no" />
表明此XSLT轉換生成是Html代碼,而且不進行縮進處理。
該XSLT模板文檔定義了兩個XSLT模板,一個是默認模板,還有一個名為“TreeNode”的子模板。默認模板內容為
<!-- ***************** 主模板,為XSLT轉換的入口點 ******************** -->
<xsl:template match="/*">
<!-- 定義一個NodeID變量,表示當前節點的編號 -->
<xsl:variable name="NodeID">
<xsl:choose>
<xsl:when test="string-length( @RootID ) > 0 ">
<xsl:value-of select="@RootID" />
</xsl:when>
<xsl:when test="string-length(ID) > 0">
<xsl:value-of select="ID" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="generate-id( . ) " />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- 若有子節點則顯示子節點 -->
<table border="0" cellspacing="0" cellpadding="0">
<xsl:attribute name="id">
<xsl:value-of select="concat( $NodeID , '_table' ) " />
</xsl:attribute>
<xsl:for-each select="Node">
<xsl:call-template name="TreeNode">
<xsl:with-param name="Level">1</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</table>
< /xsl:template>
主模板是XSLT轉換的入口處,在主模板中,首先創建了一個名為NodeID的XSLT參數,若定義了樹狀列表的根節點則創建table元素,然後循環遍歷所有的根節點,並對每一個列表節點元素調用TreeNode模板,並傳遞了一個名為Level的值為1的參數,表示生成的節點層次數。這樣就開始了遞歸創建Html元素的過程。