天天看點

asp.net夜話之十:複合控件和主機闆頁(上)

        本篇要講述的知識點如下:

TreeView控件

MultiView控件

Javascript方式的頁籤

WiZard控件

MasterPage主機闆頁

        在我們的開發中經常會遇到一些有樹形層次關系的資料,比如顯示無限級分類和顯示某個檔案下的所有檔案及檔案夾,對于這些帶有樹形層次關系的資料的顯示用TreeView控件是一個比較不錯的選擇。TreeView控件支援資料綁定也支援以程式設計的方式動态添加節點。在TreeView控件中每個節點都是一個TreeNode對象,我們可以通過TreeNode對象的Nodes屬性來添加其它的TreeNode對象,使之成為這個TreeNode對象的子節點。

        TreeView對象有以下常見屬性:

屬性名 說明

CheckedNodes 擷取選中了複選框的節點

CollapseImageUrl 節點折疊時的圖象

DataSource 綁定到TreeView控件的資料源

DataSourceID 綁定到TreeView控件的資料源控件的ID

EnableClientScript 是否允許用戶端處理展開和折疊事件

ExpandDepth 第一次顯示時所展開的級數

ExpandImageUrl 節點展開的時的圖象

NoExpandImageUrl 不可折疊(即無位元組點)的節點的圖象

PathSeparator 節點之間的值的路徑分隔符

SelectedNode 目前選中的節點

SelectedValue 目前選中的值

ShowCheckBoxes 是否在節點前顯示複選框

        下面是一個簡單的例子。我們的資料都是從一個XML檔案中讀取的,并将它的節點通過代碼的方式添加到TreeView控件中。這個XML檔案的實體檔案名為area.xml,與下面的asp.net在同一個檔案夾下,它的内容如下:

<?xml version="1.0" encoding="utf-8" ?> 

<Area> 

    <Province iAreaID ="1" cAreaName="北京市"/> 

    <Province iAreaID ="2" cAreaName="上海市"/> 

    <Province iAreaID ="3" cAreaName="天津市"/> 

    <Province iAreaID ="4" cAreaName="重慶市"/> 

    <Province iAreaID ="5" cAreaName="湖北省"> 

        <City iAreaID ="51" cAreaName="武漢市"/> 

        <City iAreaID ="52" cAreaName="黃岡市" /> 

        <City iAreaID ="53" cAreaName="荊州市"/> 

        <City iAreaID ="54" cAreaName="武穴市" /> 

        <City iAreaID ="55" cAreaName="十堰市"/> 

        <City iAreaID ="56" cAreaName="黃石市" /> 

    </Province> 

    <Province iAreaID ="6" cAreaName="河北省"> 

        <City iAreaID ="61" cAreaName="石家莊市"/> 

        <City iAreaID ="62" cAreaName="唐山市" /> 

    <Province iAreaID ="7" cAreaName="山西省"> 

        <City iAreaID ="71" cAreaName="太原市" /> 

        <City iAreaID ="72" cAreaName="大同市" /> 

</Area>

前台代碼:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TreeDemo.aspx.cs" Inherits="TreeDemo" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 

<head runat="server"> 

        <title>TreeView控件的例子</title> 

</head> 

<body> 

        <form id="form1" runat="server"> 

        <div> 

                <asp:TreeView ID="treeAreaList" runat="server" AutoGenerateDataBindings="False" OnSelectedNodeChanged="Tree_SelectedNodeChanged"> 

                </asp:TreeView> 

                </div> 

        </form> 

</body> 

</html>

        背景代碼如下:

using System; 

using System.Data; 

using System.Configuration; 

using System.Collections; 

using System.Web; 

using System.Web.Security; 

using System.Web.UI; 

using System.Web.UI.WebControls; 

using System.Web.UI.WebControls.WebParts; 

using System.Web.UI.HtmlControls; 

using System.Xml; 

using System.Xml.XPath; 

public partial class TreeDemo : System.Web.UI.Page 

        XmlDocument xmlDoc; 

void Page_Load() void Page_Load(object sender, EventArgs e) 

        { 

                if (!Page.IsPostBack) 

                { 

                        MakeParentNode(); 

                } 

        }    

//生成父結點 #region    //生成父結點    

        /// <summary>    

        /// 生成    

        /// </summary>    

void MakeParentNode() void MakeParentNode() 

                treeAreaList.Nodes.Clear(); 

                xmlDoc = new XmlDocument(); 

                xmlDoc.Load(Server.MapPath("area.xml "));//動态加載XML文檔     

                XmlNodeList nodeList = xmlDoc.SelectSingleNode("Area").ChildNodes;//擷取Area節點下的所有子結點     

                //定義Area結點     

                TreeNode topNode = new TreeNode();//定義頂級節點    

                topNode.Text = "area "; 

                //    tn.Value = "-1";     

                topNode.Expanded = true; 

                treeAreaList.Nodes.Add(topNode);//添加"區域"父結點     

                XmlElement element = null; 

                TreeNode treeNode = null; 

                //周遊區域下的所有省和直轄市     

                foreach (XmlNode node in nodeList) 

                        element = (XmlElement)node; 

                        treeNode = new TreeNode(); 

                        treeNode.Text = element.GetAttribute("cAreaName");//在樹控件上顯示省或直轄市的名稱     

                        treeNode.Value = element.GetAttribute("iAreaID");//擷取節點值    

                        treeNode.Expanded = true; 

                        topNode.ChildNodes.Add(treeNode);//将省或直轄市級結點添加到頂級節點中     

                        MakeChildNode(node.ChildNodes, treeNode);//通過遞歸将所有子節點添加到節點集合中    

        #endregion    

//生成子結點 #region    //生成子結點    

        /// 遞歸将子節點添加到目前節點下    

        /// <param name="nodeList">XmlNodeList的執行個體</param>    

        /// <param name="treeNode">要添加子節點的父節點</param>    

void MakeChildNode() void MakeChildNode(XmlNodeList nodeList, TreeNode treeNode) 

                TreeNode subTreeNode = null; 

                //周遊省級節點下的所有市,市轄區     

                        subTreeNode = new TreeNode(); 

                        subTreeNode.Text = element.GetAttribute("cAreaName");//在樹控件上顯示市或市轄區的名稱     

                        subTreeNode.Value = element.GetAttribute("iAreaID");//這裡設定節點Value    

                        subTreeNode.Expanded = true; 

                        treeNode.ChildNodes.Add(subTreeNode);//将子結點添加到父結點下面     

                        MakeChildNode(node.ChildNodes, subTreeNode);//遞歸調用本方法    

void Tree_SelectedNodeChanged() void Tree_SelectedNodeChanged(object sender, EventArgs e) 

                Response.Write("節點的值:" + treeAreaList.SelectedNode.Value+"<br/>"); 

                Response.Write("節點的路徑:" + treeAreaList.SelectedNode.ValuePath + "<br/>"); 

                Response.Write("節點的資料路徑:" + treeAreaList.SelectedNode.DataPath + "<br/>"); 

        } 

        有關XML檔案的讀取是一個比較複雜的問題,這裡在代碼中僅對程式中所使用的代碼進行了詳盡的注釋。這個頁面的運作效果如下:

        因為我們給TreeView控件的SelectedNodeChanged事件添加了處理方法,是以當我們點選節點時會進行相關的處理,下面是點選黃岡市的效果:

        MultiView控件

MultiView控件是一個比較複雜一點控件,它有點類似于WinForm中的TabControl控件,它是View控件的容器,而View控件則可以當作控件的容器,類似于WinForm中的TabPage控件。

        一次隻能設定一個View控件為活動視圖,隻有處于活動狀态的View才會呈現到用戶端。如果沒有設定任何View為活動視圖則不向用戶端呈現任何内容。可以通過設計視圖或者編碼的方式設定活動視圖。

        MultiView有兩個常見屬性:

ActiveViewIndex: 目前活動的View索引,我們通常就是通過設定ActiveViewIndex來控制View的顯示的。

Views:目前MultiView控件的View集合

        下面是一個利用MultiView控件實作的類似于Windows應用程式中的頁籤式效果。前台設計代碼如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MultiViewDemo.aspx.cs" Inherits="MultiViewDemo"%> 

        <title>MultiView應用執行個體</title> 

        <style type="text/css"> 

        body 

        font-size: 11pt; 

        font-family: 宋體; 

.mainTitle 

        font-size: 12pt; 

        font-weight: bold; 

.commonText 

.littleMainTitle 

        font-size: 10pt; 

.TopTitle 

        border: 0px; 

        text-decoration: none; 

        color: Black; 

        display: inline-block; 

        width: 100%;         

.SelectedTopTitle 

        width: 100%; 

        background-color: White; 

.ContentView 

        padding: 3px 3px 3px 3px; 

        width: 390px; 

.SepBorder 

        border-top-width: 0px; 

        border-left-width: 0px; 

        font-size: 1px; 

        border-bottom: Gray 1px solid; 

        border-right-width: 0px; 

.TopBorder 

        border-right: Gray 1px solid; 

        border-top: Gray 1px solid; 

        background: #DCDCDC; 

        border-left: Gray 1px solid; 

        color: black; 

.ContentBorder 

        border-top: Gray 0px solid; 

        height: 100%; 

.SelectedTopBorder 

        background: none transparent scroll repeat 0% 0%; 

        border-bottom: Gray 0px solid; 

        </style> 

        <fieldset style="width:400px"> 

                        <legend>MultiView應用執行個體</legend> 

                        <table cellpadding="0" cellspacing="0" width="100%" border="0"> 

                                <tr> 

                                        <td> 

                                                <table id="Table1" runat="server" cellpadding="0" cellspacing="0" width="100%"border="0"> 

                                                        <tr style="height:22px"> 

                                                                <td class="SelectedTopBorder" id="Cell1" align="center" style="width:80px;"> 

                                                                        <asp:LinkButton ID="lButtonCompany" runat="server" OnClick="lButtonCompany_Click">公司介紹</asp:LinkButton></td> 

                                                                <td class="SepBorder" style="width:2px; height: 22px;"></td> 

                                                                <td class="TopBorder" id="Cell2" align="center" style="width:80px;"> 

                                                                        <asp:LinkButton ID="lButtonProduct" runat="server" OnClick="lButtonProduct_Click">産品介紹</asp:LinkButton></td> 

                                                                <td class="TopBorder" id="Cell3" align="center" style="width:80px;"> 

                                                                        <asp:LinkButton ID="lButtonContact" runat="server" OnClick="lButtonContact_Click">聯系我們</asp:LinkButton></td> 

                                                        </tr> 

                                                </table> 

                                        </td> 

                                </tr> 

                                                <table class="ContentBorder" cellpadding="0" cellspacing="0" width="100%"> 

                                                            <tr> 

                                                                    <td valign="top"> 

                                                                            <asp:MultiView ID="mvCompany" runat="server" ActiveViewIndex="0"> 

                                                                                    <asp:View ID="View1" runat="server"> 

                                                                                                                我們公司是一個正在上升時期的公司。公司目前有中科院計算機院士3人,博士後32人,博士63人,研究所學生120人,大學生356人,具有非常強大研發實力。</asp:View> 

                                                                                    <asp:View ID="View2" runat="server"> 

                                                                                            我們有豐富的産品線,還可以為使用者單獨定制。目前有CMS文章釋出系統、CRM客戶資源關系管理系統、OA自動辦公系統、BBS論壇系統及ERP企業資産管理系統等等,正在研發的軟體有GPS車輛定位導航系統及工作流定制系統等等。</asp:View> 

                                                                                    <asp:View ID="View3" runat="server"> 

                                                                                            本公司熱烈歡迎技術界和銷售界的精英加入我們的團隊,待遇優厚。我們的聯系方式是119,傳真是110,客服電話是120,售後電話114。</asp:View> 

                                                                             </asp:MultiView> 

                                                                    </td> 

                                                            </tr> 

                                                     </table> 

                                             </td> 

                                    </tr> 

                        </table> 

                </fieldset> 

        </div> 

</html> 

        背景程式代碼如下:

public partial class MultiViewDemo : System.Web.UI.Page 

        /// 點選公司介紹時的css設定    

        /// <param name="sender"></param>    

        /// <param name="e"></param>    

void lButtonCompany_Click() void lButtonCompany_Click(object sender, EventArgs e) 

                mvCompany.ActiveViewIndex = 0; 

                Cell1.Attributes["class"] = "SelectedTopBorder"; 

                Cell2.Attributes["class"] = "TopBorder"; 

                Cell3.Attributes["class"] = "TopBorder"; 

        /// 點選産品介紹時的css設定    

void lButtonProduct_Click() void lButtonProduct_Click(object sender, EventArgs e) 

                mvCompany.ActiveViewIndex = 1; 

                Cell1.Attributes["class"] = "TopBorder"; 

                Cell2.Attributes["class"] = "SelectedTopBorder"; 

        /// 點選聯系我們時的css設定    

void lButtonContact_Click() void lButtonContact_Click(object sender, EventArgs e) 

                mvCompany.ActiveViewIndex = 2; 

                Cell3.Attributes["class"] = "SelectedTopBorder"; 

        頁面在設計視圖狀态下的效果:

        下面分别是點選“公司介紹”、“産品介紹”及“聯系我們”時的效果。

“公司介紹”效果

        “産品介紹”效果

        “聯系我們”效果

        因為在上面的實作方式中每次點選都會引起向伺服器回傳,在實際項目中有時候也會采用javascript來實作類似的頁籤式效果。用javascript實作頁籤式效果比使用MultiView控件實作頁籤式效果要複雜一些,因為要編寫一些用戶端腳本代碼。

下面是一個用javascript來實作的頁籤式效果的例子,完全采用輸出HTML代碼的方式。在這個例子中我們通過css和div來控制目前活動頁籤和非活動頁籤的顯示與否及顯示樣式,疑難部分筆者都做了詳盡注釋,讀者朋友完全可以根據自己的實際需要把代碼改造成自己想要的效果。

        以下是設計部分代碼:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="JavaScriptMenu.aspx.cs" Inherits="JavaScriptMenu" %> 

        <title>JavaScript實作的頁籤式效果</title> 

        <script language="javascript" type="text/javascript"> 

        function Show_Sub(id_num,num,obj) 

        {    

                for(var i = 0;i <= 9;i++) 

                        if(GetObj("tabb" + id_num + i)) 

                        { 

                                GetObj("tabb" + id_num + i).className = 'guide2'; 

                        } 

                        if(GetObj("subb" + id_num + i)) 

                                GetObj("subb" + id_num + i).style.display = 'none'; 

                if(GetObj("tabb" + id_num + num)) 

                        GetObj("tabb" + id_num + num).className = 'guide1'; 

                if(GetObj("subb" + id_num + num)) 

                        GetObj("subb" + id_num + num).style.display = 'block'; 

        function GetObj(objName) 

                if(document.getElementById) 

                        return eval('document.getElementById("' + objName + '")'); 

                else 

                        return eval('document.all.' + objName); 

</script> 

<style type="text/css"> 

.guide1 { 

cursor: hand; 

color: #003399; 

background-color:#3399FF; 

font-weight: bold; 

text-decoration: none; 

border-right: 1px solid #A2C0FE; 

height: 25px; 

line-height: 25px; 

.guide2 { 

.24line {line-height: 24px;} 

.pad5 {padding:5px;} 

.padtop2 {padding-top:2px;} 

.padtop5 {padding-top:5px;} 

.t {border-top: 1px solid #A2C0FE;} 

.b {border-bottom: 1px solid #A2C0FE;} 

.l {border-left: 1px solid #A2C0FE;} 

.r {border-right: 1px solid #A2C0FE;} 

.right{ 

float:right; 

color: #999999; 

.left{ 

float:left; 

</style> 

        <%=GetUserPanel(0) %> 

        下面是背景代碼:

using System.Text; 

using System.Data.SqlClient; 

public partial class JavaScriptMenu : System.Web.UI.Page 

        protected void Page_Load(object sender, EventArgs e) 

        //在本頁面中多次要查詢資料庫,為了簡單起見,把對資料庫的查詢操作提出來作為一個單獨的方法    

        //這個方法會根據查詢SQL語句的不同而傳回不同資料的DataTable    

        private DataTable GetDataTable(string sql) 

                SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 

                SqlCommand command = new SqlCommand(sql, connection); 

                SqlDataAdapter adapter = new SqlDataAdapter(command); 

                DataTable data = new DataTable(); 

                adapter.Fill(data); 

                return data; 

        /// <summary>    

        /// 按照UserName字段的首字母順序查找使用者,并以類似于頁籤的方式顯示出來    

        /// 說明:在實際項目中可能一個頁面要輸出多個頁籤式效果,可以以不同的type來區分    

        /// 以達到公用一個方法的目的    

        /// </summary>    

        /// <param name="type">類别編号</param>    

        /// <returns></returns>    

        public string GetUserPanel(int type) 

                //因為多次需要操作字元串,為提高性能使用了System.Text.StringBuilder類而非string類    

                StringBuilder text = new StringBuilder(4096); 

                //表頭    

                text.AppendLine("<!--------start----->"); 

                text.AppendLine("<table width=\"400\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 

                text.AppendLine("<tr>"); 

                text.AppendLine("<td height=\"168\" valign=\"top\" class=\"padtop2\"><table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 

                text.AppendLine("<td height=\"168\" valign=\"top\" class=\"pad5 24line b l t r\">\n<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 

                text.AppendLine("<td><table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"l t b\">\n"); 

                //這裡僅列出UserName字段首字母為'c','d','l','z'的使用者    

                char[] firstChar=new char[]{'c','d','l','z'};    

                #region 輸出頁籤标簽    

                for (int i = 0; i < firstChar.Length; i++) 

                        text.AppendLine("<td    class=\"guide" + ((i + 1) >= 2 ? 2 : 1) + "\" id=\"tabb" + type + "" + i + "\" + type + "," + i + ",this) align=\"center\">" + firstChar[i] + "</td>"); 

                }    

                #endregion    

                text.AppendLine("</tr></table>"); 

                text.AppendLine("</td></tr><tr><td class=\"padtop5\">");    

                #region 輸出每個頁籤下的使用者    

                        if (i == 0) 

                                text.AppendLine("<div id=\"subb" + type + i + "\"    class=\"24line\">\n"); 

                        else 

                                text.AppendLine("<div id=\"subb" + type + i + "\"    style=\"DISPLAY: none\"    class=\"24line\">\n"); 

                        DataTable dataPersonList = GetDataTable("select UserName,RealName from UserInfo where UserName like '" + firstChar[i] + "%'"); 

                        DataRow row = null; 

                        //輸出每個使用者的資訊    

                        for (int j = 0; j < dataPersonList.Rows.Count; j++) 

                                row = dataPersonList.Rows[j];                                 

                                text.AppendLine("<div class=\"left\">" + row["UserName"].ToString() + "</div>"); 

                                text.Append("<div class=\"right\">" + row["RealName"].ToString() + "</div>"); 

                                text.AppendLine("</br>"); 

                        text.AppendLine("</div>"); 

                text.AppendLine("</td>\n</tr>\n</table>\n</td>\n</tr></table></td></tr></table>"); 

                text.AppendLine("<!------end--->"); 

                return text.ToString(); 

        這個程式顯示效果如下:

        點選“z”頁籤時的效果:

        用Javascript實作的頁籤式效果比用MultiView控件實作同樣的效果要複雜很多,但是它有一個有點就是在頁籤之間切換時不用每次重新整理頁面和讀取資料庫。

        WiZard控件

WiZard控件非常類似于我們常見的Windows中的向導控件,用于分步驟收集使用者送出的資料。

        下面是拖入一個WiZard控件到空白頁面的效果:

        和MultiView類似,WiZard是一個WizardStepBase的容器,每個WizardStepBase類似于一個View。與MultiView不同的是,WizardStepBase上顯示有上下步驟之間的導航,我們可以控制目前WizardStepBase中的導航樣式,這可以通過WizardStepBase的StepType屬性來控制。如果進行設定,那麼每個WizardStepBase的StepType屬性為Auto。下面列出了WizardStepBase的StepType屬性的所有可能值:

StepType值 顯示行為和結果

WizardStepType.Auto 由聲明該WizardStepBase的順序決定

WizardStepType.Complete 整個步驟最後一步,不顯示任何導航按鈕

WizardStepType.Finish 收集資料的最後一步,顯示“完成”導航按鈕

WizardStepType.Start 要顯示的第一個步驟,不顯示“上一步”導航按鈕

WizardStepType.Step 介于第一個和最後一個步驟,顯示“上一步”、“下一步”按鈕

本文轉自周金橋51CTO部落格,原文連結:http://blog.51cto.com/zhoufoxcn/166455 ,如需轉載請自行聯系原作者