asp.net夜话之十:复合控件和母板页

《asp.net夜话》封面

 

本篇要讲述的知识点如下:
TreeView控件
MultiView控件
Javascript方式的选项卡
WiZard控件
MasterPage母板页

 

TreeView控件
在我们的开发中经常会遇到一些有树形层次关系的数据,比如显示无限级分类和显示某个文件下的所有文件及文件夹,对于这些带有树形层次关系的数据的显示用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在同一个文件夹下,它的内容如下:

 

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <Area>
  3.   <Province iAreaID ="1" cAreaName="北京市"/>
  4.   <Province iAreaID ="2" cAreaName="上海市"/>
  5.   <Province iAreaID ="3" cAreaName="天津市"/>
  6.   <Province iAreaID ="4" cAreaName="重庆市"/>
  7.   <Province iAreaID ="5" cAreaName="湖北省">
  8.     <City iAreaID ="51" cAreaName="武汉市"/>
  9.     <City iAreaID ="52" cAreaName="黄冈市" />
  10.     <City iAreaID ="53" cAreaName="荆州市"/>
  11.     <City iAreaID ="54" cAreaName="武穴市" />
  12.     <City iAreaID ="55" cAreaName="十堰市"/>
  13.     <City iAreaID ="56" cAreaName="黄石市" />
  14.   </Province>
  15.   <Province iAreaID ="6" cAreaName="河北省">
  16.     <City iAreaID ="61" cAreaName="石家庄市"/>
  17.     <City iAreaID ="62" cAreaName="唐山市" />
  18.   </Province>
  19.   <Province iAreaID ="7" cAreaName="山西省">
  20.     <City iAreaID ="71" cAreaName="太原市" />
  21.     <City iAreaID ="72" cAreaName="大同市" />
  22.   </Province>
  23. </Area>

前台代码:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="TreeDemo.aspx.cs" Inherits="TreeDemo" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>TreeView控件的例子</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.         <asp:TreeView ID="treeAreaList" runat="server" AutoGenerateDataBindings="False" OnSelectedNodeChanged="Tree_SelectedNodeChanged">
  11.         </asp:TreeView>
  12.         </div>
  13.     </form>
  14. </body>
  15. </html>

后台代码如下:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. using System.Xml;
  12. using System.Xml.XPath;
  13. public partial class TreeDemo : System.Web.UI.Page
  14. {
  15.     XmlDocument xmlDoc;
  16.     protected void Page_Load(object sender, EventArgs e)
  17.     {
  18.         if (!Page.IsPostBack)
  19.         {
  20.             MakeParentNode();
  21.         }
  22.     }
  23.     #region  //生成父结点
  24.     /// <summary>
  25.     /// 生成
  26.     /// </summary>
  27.     protected void MakeParentNode()
  28.     {
  29.         treeAreaList.Nodes.Clear();
  30.         xmlDoc = new XmlDocument();
  31.         xmlDoc.Load(Server.MapPath("area.xml "));//动态加载XML文档 
  32.         XmlNodeList nodeList = xmlDoc.SelectSingleNode("Area").ChildNodes;//获取Area节点下的所有子结点 
  33.         //定义Area结点 
  34.         TreeNode topNode = new TreeNode();//定义顶级节点
  35.         topNode.Text = "area ";
  36.         //  tn.Value = "-1"; 
  37.         topNode.Expanded = true;
  38.         treeAreaList.Nodes.Add(topNode);//添加"区域"父结点 
  39.         XmlElement element = null;
  40.         TreeNode treeNode = null;
  41.         //遍历区域下的所有省和直辖市 
  42.         foreach (XmlNode node in nodeList)
  43.         {
  44.             element = (XmlElement)node;
  45.             treeNode = new TreeNode();
  46.             treeNode.Text = element.GetAttribute("cAreaName");//在树控件上显示省或直辖市的名称 
  47.             treeNode.Value = element.GetAttribute("iAreaID");//获取节点值
  48.             treeNode.Expanded = true;
  49.             topNode.ChildNodes.Add(treeNode);//将省或直辖市级结点添加到顶级节点中 
  50.             MakeChildNode(node.ChildNodes, treeNode);//通过递归将所有子节点添加到节点集合中
  51.         }
  52.     }
  53.     #endregion
  54.     #region  //生成子结点
  55.     /// <summary>
  56.     /// 递归将子节点添加到当前节点下
  57.     /// </summary>
  58.     /// <param name="nodeList">XmlNodeList的实例</param>
  59.     /// <param name="treeNode">要添加子节点的父节点</param>
  60.     protected void MakeChildNode(XmlNodeList nodeList, TreeNode treeNode)
  61.     {
  62.         XmlElement element = null;
  63.         TreeNode subTreeNode = null;
  64.         //遍历省级节点下的所有市,市辖区 
  65.         foreach (XmlNode node in nodeList)
  66.         {
  67.             element = (XmlElement)node;
  68.             subTreeNode = new TreeNode();
  69.             subTreeNode.Text = element.GetAttribute("cAreaName");//在树控件上显示市或市辖区的名称 
  70.             subTreeNode.Value = element.GetAttribute("iAreaID");//这里设置节点Value
  71.             subTreeNode.Expanded = true;
  72.             treeNode.ChildNodes.Add(subTreeNode);//将子结点添加到父结点下面 
  73.             MakeChildNode(node.ChildNodes, subTreeNode);//递归调用本方法
  74.         }
  75.     }
  76.     #endregion
  77.     protected void Tree_SelectedNodeChanged(object sender, EventArgs e)
  78.     {
  79.         Response.Write("节点的值:" + treeAreaList.SelectedNode.Value+"<br/>");
  80.         Response.Write("节点的路径:" + treeAreaList.SelectedNode.ValuePath + "<br/>");
  81.         Response.Write("节点的数据路径:" + treeAreaList.SelectedNode.DataPath + "<br/>");
  82.     }
  83. }


有关XML文件的读取是一个比较复杂的问题,这里在代码中仅对程序中所使用的代码进行了详尽的注释。这个页面的运行效果如下:
 
因为我们给TreeView控件的SelectedNodeChanged事件添加了处理方法,所以当我们点击节点时会进行相关的处理,下面是点击黄冈市的效果:

 

MultiView控件
MultiView控件是一个比较复杂一点控件,它有点类似于WinForm中的TabControl控件,它是View控件的容器,而View控件则可以当作控件的容器,类似于WinForm中的TabPage控件。
一次只能设置一个View控件为活动视图,只有处于活动状态的View才会呈现到客户端。如果没有设置任何View为活动视图则不向客户端呈现任何内容。可以通过设计视图或者编码的方式设置活动视图。
MultiView有两个常见属性:
ActiveViewIndex: 当前活动的View索引,我们通常就是通过设置ActiveViewIndex来控制View的显示的。
Views:当前MultiView控件的View集合
下面是一个利用MultiView控件实现的类似于Windows应用程序中的选项卡式效果。前台设计代码如下:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="MultiViewDemo.aspx.cs" Inherits="MultiViewDemo" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>MultiView应用实例</title>
  6.     <style type="text/css">
  7.     body
  8. {
  9.     font-size: 11pt;
  10.     font-family: 宋体;
  11. }
  12. .mainTitle
  13. {
  14.     font-size: 12pt;
  15.     font-weight: bold;
  16.     font-family: 宋体;
  17. }
  18. .commonText
  19. {
  20.     font-size: 11pt;
  21.     font-family: 宋体;
  22. }
  23. .littleMainTitle
  24. {
  25.     font-size: 10pt;
  26.     font-weight: bold;
  27.     font-family: 宋体;
  28. }
  29. .TopTitle
  30. {
  31.     border: 0px;
  32.     font-size: 10pt;
  33.     font-weight: bold;
  34.     text-decoration: none;
  35.     color: Black;
  36.     display: inline-block;
  37.     width: 100%;    
  38. }
  39. .SelectedTopTitle
  40. {
  41.     border: 0px;
  42.     font-size: 10pt;
  43.     text-decoration: none;
  44.     color: Black;
  45.     display: inline-block;
  46.     width: 100%;
  47.     background-color: White;
  48. }
  49. .ContentView
  50. {
  51.     border: 0px;
  52.     padding: 3px 3px 3px 3px;
  53.     background-color: White;
  54.     display: inline-block;
  55.     width: 390px;
  56. }
  57. .SepBorder
  58. {
  59.     border-top-width: 0px;
  60.     border-left-width: 0px;
  61.     font-size: 1px;
  62.     border-bottom: Gray 1px solid;
  63.     border-right-width: 0px;
  64. }
  65. .TopBorder
  66. {
  67.     border-right: Gray 1px solid;
  68.     border-top: Gray 1px solid;
  69.     background: #DCDCDC;
  70.     border-left: Gray 1px solid;
  71.     color: black;
  72.     border-bottom: Gray 1px solid;
  73. }
  74. .ContentBorder
  75. {
  76.     border-right: Gray 1px solid;
  77.     border-top: Gray 0px solid;
  78.     border-left: Gray 1px solid;
  79.     border-bottom: Gray 1px solid;
  80.     height: 100%;
  81.     width: 100%;
  82. }
  83. .SelectedTopBorder
  84. {
  85.     border-right: Gray 1px solid;
  86.     border-top: Gray 1px solid;
  87.     background: none transparent scroll repeat 0% 0%;
  88.     border-left: Gray 1px solid;
  89.     color: black;
  90.     border-bottom: Gray 0px solid;
  91. }
  92.     </style>
  93. </head>
  94. <body>
  95.     <form id="form1" runat="server">
  96.     <div>
  97.     <fieldset style="width:400px">
  98.             <legend>MultiView应用实例</legend>
  99.             <table cellpadding="0" cellspacing="0" width="100%" border="0">
  100.                 <tr>
  101.                     <td>
  102.                         <table id="Table1" runat="server" cellpadding="0" cellspacing="0" width="100%" border="0">
  103.                             <tr style="height:22px">
  104.                                 <td class="SelectedTopBorder" id="Cell1" align="center" style="width:80px;">
  105.                                     <asp:LinkButton ID="lButtonCompany" runat="server" OnClick="lButtonCompany_Click">公司介绍</asp:LinkButton></td>
  106.                                 <td class="SepBorder" style="width:2px; height: 22px;"></td>
  107.                                 <td class="TopBorder" id="Cell2" align="center" style="width:80px;">
  108.                                     <asp:LinkButton ID="lButtonProduct" runat="server" OnClick="lButtonProduct_Click">产品介绍</asp:LinkButton></td>
  109.                                 <td class="SepBorder" style="width:2px; height: 22px;"></td>
  110.                                 <td class="TopBorder" id="Cell3" align="center" style="width:80px;">
  111.                                     <asp:LinkButton ID="lButtonContact" runat="server" OnClick="lButtonContact_Click">联系我们</asp:LinkButton></td>
  112.                                 <td class="SepBorder" style="width:2px; height: 22px;"></td>
  113.                             </tr>
  114.                         </table>
  115.                     </td>
  116.                 </tr>
  117.                 <tr>
  118.                     <td>
  119.                         <table class="ContentBorder" cellpadding="0" cellspacing="0" width="100%">
  120.                               <tr>
  121.                                   <td valign="top">
  122.                                       <asp:MultiView ID="mvCompany" runat="server" ActiveViewIndex="0">
  123.                                           <asp:View ID="View1" runat="server">
  124.                                                         我们公司是一个正在上升时期的公司。公司目前有中科院计算机院士3人,博士后32人,博士63人,研究生120人,本科生356人,具有非常强大研发实力。</asp:View>
  125.                                           <asp:View ID="View2" runat="server">
  126.                                               我们有丰富的产品线,还可以为用户单独定制。目前有CMS文章发布系统、CRM客户资源关系管理系统、OA自动办公系统、BBS论坛系统及ERP企业资产管理系统等等,正在研发的软件有GPS车辆定位导航系统及工作流定制系统等等。</asp:View>
  127.                                           <asp:View ID="View3" runat="server">
  128.                                               本公司热烈欢迎技术界和销售界的精英加入我们的团队,待遇优厚。我们的联系方式是119,传真是110,客服电话是120,售后电话114。</asp:View>
  129.                                        </asp:MultiView>
  130.                                   </td>
  131.                               </tr>
  132.                            </table>
  133.                        </td>
  134.                   </tr>
  135.             </table>
  136.         </fieldset>
  137.     </div>
  138.     </form>
  139. </body>
  140. </html>

后台程序代码如下:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class MultiViewDemo : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.     }
  16.     /// <summary>
  17.     /// 点击公司介绍时的css设置
  18.     /// </summary>
  19.     /// <param name="sender"></param>
  20.     /// <param name="e"></param>
  21.     protected void lButtonCompany_Click(object sender, EventArgs e)
  22.     {
  23.         mvCompany.ActiveViewIndex = 0;
  24.         Cell1.Attributes["class"] = "SelectedTopBorder";
  25.         Cell2.Attributes["class"] = "TopBorder";
  26.         Cell3.Attributes["class"] = "TopBorder";
  27.     }
  28.     /// <summary>
  29.     /// 点击产品介绍时的css设置
  30.     /// </summary>
  31.     /// <param name="sender"></param>
  32.     /// <param name="e"></param>
  33.     protected void lButtonProduct_Click(object sender, EventArgs e)
  34.     {
  35.         mvCompany.ActiveViewIndex = 1;
  36.         Cell1.Attributes["class"] = "TopBorder";
  37.         Cell2.Attributes["class"] = "SelectedTopBorder";
  38.         Cell3.Attributes["class"] = "TopBorder";
  39.     }
  40.     /// <summary>
  41.     /// 点击联系我们时的css设置
  42.     /// </summary>
  43.     /// <param name="sender"></param>
  44.     /// <param name="e"></param>
  45.     protected void lButtonContact_Click(object sender, EventArgs e)
  46.     {
  47.         mvCompany.ActiveViewIndex = 2;
  48.         Cell1.Attributes["class"] = "TopBorder";
  49.         Cell2.Attributes["class"] = "TopBorder";
  50.         Cell3.Attributes["class"] = "SelectedTopBorder";
  51.     }
  52. }


页面在设计视图状态下的效果:
 
下面分别是点击“公司介绍”、“产品介绍”及“联系我们”时的效果。
“公司介绍”效果
 
“产品介绍”效果
 
“联系我们”效果
 
因为在上面的实现方式中每次点击都会引起向服务器回传,在实际项目中有时候也会采用javascript来实现类似的选项卡式效果。用javascript实现选项卡式效果比使用MultiView控件实现选项卡式效果要复杂一些,因为要编写一些客户端脚本代码。
下面是一个用javascript来实现的选项卡式效果的例子,完全采用输出HTML代码的方式。在这个例子中我们通过css和div来控制当前活动选项卡和非活动选项卡的显示与否及显示样式,疑难部分笔者都做了详尽注释,读者朋友完全可以根据自己的实际需要把代码改造成自己想要的效果。
以下是设计部分代码:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="JavaScriptMenu.aspx.cs" Inherits="JavaScriptMenu" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>JavaScript实现的选项卡式效果</title>
  6.     <script language="javascript" type="text/javascript">
  7.     function Show_Sub(id_num,num,obj)
  8.     { 
  9.         for(var i = 0;i <= 9;i++)
  10.         {
  11.             if(GetObj("tabb" + id_num + i))
  12.             {
  13.                 GetObj("tabb" + id_num + i).className = 'guide2';
  14.             }
  15.             if(GetObj("subb" + id_num + i))
  16.             {
  17.                 GetObj("subb" + id_num + i).style.display = 'none';
  18.             }
  19.         }
  20.         if(GetObj("tabb" + id_num + num))
  21.         {
  22.             GetObj("tabb" + id_num + num).className = 'guide1';
  23.         }
  24.         if(GetObj("subb" + id_num + num))
  25.         {
  26.             GetObj("subb" + id_num + num).style.display = 'block';
  27.         }
  28.     }
  29.     function GetObj(objName)
  30.     {
  31.         if(document.getElementById)
  32.         {
  33.             return eval('document.getElementById("' + objName + '")');
  34.         }
  35.         else
  36.         {
  37.             return eval('document.all.' + objName);
  38.         }
  39.     }
  40. </script>
  41. <style type="text/css">
  42. .guide1 {
  43.  cursor: hand;
  44.  color: #003399;
  45.  background-color:#3399FF;
  46.  font-weight: bold;
  47.  text-decoration: none;
  48.  border-right: 1px solid #A2C0FE;
  49.  height: 25px;
  50.  line-height: 25px;
  51. }
  52. .guide2 {
  53.  cursor: hand;
  54.  border-right: 1px solid #A2C0FE;
  55.  line-height: 25px;
  56. }
  57. .24line {line-height: 24px;}
  58. .pad5 {padding:5px;}
  59. .padtop2 {padding-top:2px;}
  60. .padtop5 {padding-top:5px;}
  61. .t {border-top: 1px solid #A2C0FE;}
  62. .b {border-bottom: 1px solid #A2C0FE;}
  63. .l {border-left: 1px solid #A2C0FE;}
  64. .r {border-right: 1px solid #A2C0FE;}
  65. .right{
  66.  float:right;
  67.  color: #999999;
  68.  }
  69. .left{
  70.  float:left;
  71.  color: #999999;
  72.  }
  73. </style>
  74. </head>
  75. <body>
  76.     <form id="form1" runat="server">
  77.     <div>
  78.     <%=GetUserPanel(0) %>
  79.     </div>
  80.     </form>
  81. </body>
  82. </html>

下面是后台代码:


 

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. using System.Text;
  12. using System.Data.SqlClient;
  13. public partial class JavaScriptMenu : System.Web.UI.Page
  14. {
  15.     protected void Page_Load(object sender, EventArgs e)
  16.     {
  17.     }
  18.     //在本页面中多次要查询数据库,为了简单起见,把对数据库的查询操作提出来作为一个单独的方法
  19.     //这个方法会根据查询SQL语句的不同而返回不同数据的DataTable
  20.     private DataTable GetDataTable(string sql)
  21.     {
  22.         SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
  23.         SqlCommand command = new SqlCommand(sql, connection);
  24.         SqlDataAdapter adapter = new SqlDataAdapter(command);
  25.         DataTable data = new DataTable();
  26.         adapter.Fill(data);
  27.         return data;
  28.     }
  29.     /// <summary>
  30.     /// 按照UserName字段的首字母顺序查找用户,并以类似于选项卡的方式显示出来
  31.     /// 说明:在实际项目中可能一个页面要输出多个选项卡式效果,可以以不同的type来区分
  32.     /// 以达到公用一个方法的目的
  33.     /// </summary>
  34.     /// <param name="type">类别编号</param>
  35.     /// <returns></returns>
  36.     public string GetUserPanel(int type)
  37.     {
  38.         //因为多次需要操作字符串,为提高性能使用了System.Text.StringBuilder类而非string类
  39.         StringBuilder text = new StringBuilder(4096);
  40.         //表头
  41.         text.AppendLine("<!--------start----->");
  42.         text.AppendLine("<table width=/"400/" border=/"0/" cellspacing=/"0/" cellpadding=/"0/">");
  43.         text.AppendLine("<tr>");
  44.         text.AppendLine("<td height=/"168/" valign=/"top/" class=/"padtop2/"><table width=/"100%/" border=/"0/" cellspacing=/"0/" cellpadding=/"0/">");
  45.         text.AppendLine("<tr>");
  46.         text.AppendLine("<td height=/"168/" valign=/"top/" class=/"pad5 24line b l t r/">/n<table width=/"100%/" border=/"0/" cellspacing=/"0/" cellpadding=/"0/">");
  47.         text.AppendLine("<tr>");
  48.         text.AppendLine("<td><table width=/"100%/" border=/"0/" cellpadding=/"0/" cellspacing=/"0/" class=/"l t b/">/n");
  49.         text.AppendLine("<tr>");
  50.         //这里仅列出UserName字段首字母为'c','d','l','z'的用户
  51.         char[] firstChar=new char[]{'c','d','l','z'};
  52.         #region 输出选项卡标签
  53.         for (int i = 0; i < firstChar.Length; i++)
  54.         {
  55.             text.AppendLine("<td  class=/"guide" + ((i + 1) >= 2 ? 2 : 1) + "/" id=/"tabb" + type + "" + i + "/" οnmοusemοve=Show_Sub(" + type + "," + i + ",this) align=/"center/">" + firstChar[i] + "</td>");
  56.         }
  57.         #endregion
  58.         text.AppendLine("</tr></table>");
  59.         text.AppendLine("</td></tr><tr><td class=/"padtop5/">");
  60.         #region 输出每个选项卡下的用户
  61.         for (int i = 0; i < firstChar.Length; i++)
  62.         {
  63.             if (i == 0)
  64.             {
  65.                 text.AppendLine("<div id=/"subb" + type + i + "/"  class=/"24line/">/n");
  66.             }
  67.             else
  68.             {
  69.                 text.AppendLine("<div id=/"subb" + type + i + "/"  style=/"DISPLAY: none/"  class=/"24line/">/n");
  70.             }
  71.             DataTable dataPersonList = GetDataTable("select UserName,RealName from UserInfo where UserName like '" + firstChar[i] + "%'");
  72.             DataRow row = null;
  73.             //输出每个用户的信息
  74.             for (int j = 0; j < dataPersonList.Rows.Count; j++)
  75.             {
  76.                 row = dataPersonList.Rows[j];                
  77.                 text.AppendLine("<div class=/"left/">" + row["UserName"].ToString() + "</div>");
  78.                 text.Append("<div class=/"right/">" + row["RealName"].ToString() + "</div>");
  79.                 text.AppendLine("</br>");
  80.             }
  81.             text.AppendLine("</div>");
  82.         }
  83.         #endregion
  84.         text.AppendLine("</td>/n</tr>/n</table>/n</td>/n</tr></table></td></tr></table>");
  85.         text.AppendLine("<!------end--->");
  86.         return text.ToString();
  87.     }
  88. }

这个程序显示效果如下:
 
点击“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介于第一个和最后一个步骤,显示“上一步”、“下一步”按钮

在页面中添加一个Wizard控件之后,点击“添加/移除WiZardSteps…”按钮,出现如下界面:
 
我们可以设置每一个步骤的Title属性,这个属性是显示每个步骤的名称的。然后再添加每个步骤应该显示的内容。
下面以代码模拟一个找回密码的功能,前台代码如下:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="WiZardDemo.aspx.cs" Inherits="WiZardDemo" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>WiZard控件用法</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.         <asp:Wizard ID="Wizard1" runat="server" ActiveStepIndex="0" Width="400" OnActiveStepChanged="Wizard1_ActiveStepChanged">
  11.             <WizardSteps>
  12.                 <asp:WizardStep runat="server" Title="第一步" StepType="Start">
  13.                 <table border="0" cellpadding="0" cellspacing="0">
  14.                 <tr><td>请输入用户名</td><td><asp:TextBox runat="server" ID="txtUserName"></asp:TextBox></td></tr>
  15.                 </table>
  16.                     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" Display="Dynamic"
  17.                         ErrorMessage="请输入用户名" ControlToValidate="txtUserName"></asp:RequiredFieldValidator>
  18.                 </asp:WizardStep>
  19.                 <asp:WizardStep runat="server" Title="第二步" StepType="Step">
  20.                 <table border="0" cellpadding="0" cellspacing="0">
  21.                 <tr><td>你的密码提示问题</td><td><asp:Label runat="server" ID="lbQuestion"></asp:Label></td></tr>
  22.                 <tr><td>你的密码提示答案</td><td><asp:TextBox runat="server" ID="txtAnswer"></asp:TextBox></td></tr>
  23.                 </table>
  24.                     <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtAnswer"
  25.                         ErrorMessage="请输入密码提示答案"></asp:RequiredFieldValidator>
  26.                 </asp:WizardStep>
  27.                 <asp:WizardStep runat="server" StepType="Finish" Title="第三步">
  28.                 <table border="0" cellpadding="0" cellspacing="0">
  29.                 <tr><td>请输入新密码</td><td>
  30.                     <asp:TextBox ID="txtPassword" runat="server"></asp:TextBox>
  31.                 </td></tr>
  32.                 <tr><td>请确认新密码</td><td><asp:TextBox runat="server" ID="txtCPassword"></asp:TextBox></td></tr>
  33.                 </table>
  34.                     <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="txtPassword"
  35.                         Display="Dynamic" ErrorMessage="请输入新密码"></asp:RequiredFieldValidator>
  36.                     <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="txtCPassword"
  37.                         Display="Dynamic" ErrorMessage="请确认新密码"></asp:RequiredFieldValidator>
  38.                     <asp:CompareValidator ID="CompareValidator1" runat="server" ControlToCompare="txtPassword"
  39.                         ControlToValidate="txtCPassword" ErrorMessage="两次密码不一致"></asp:CompareValidator>
  40.                 </asp:WizardStep>
  41.                 <asp:WizardStep runat="server" StepType="Complete" Title="第四步">
  42.                 恭喜,密码更改成功。
  43.                 </asp:WizardStep>
  44.             </WizardSteps>
  45.             <HeaderTemplate>
  46.                 找回密码
  47.             </HeaderTemplate>
  48.         </asp:Wizard>
  49.     
  50.     </div>
  51.     </form>
  52. </body>
  53. </html>

后台代码如下

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class WiZardDemo : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.     }
  16.     protected void Wizard1_ActiveStepChanged(object sender, EventArgs e)
  17.     {
  18.         
  19.         if (Wizard1.ActiveStepIndex == 1)//当用户进入找回密码第二步
  20.         {
  21.             //如果用户输入的是"admin"则提示用户输入"123456"
  22.             if (txtUserName.Text == "admin")
  23.             {
  24.                 lbQuestion.Text = "请输入123456";
  25.             }
  26.             else//如果用户输入的用户名不是"admin"则跳转到第一步
  27.             {
  28.                 Wizard1.ActiveStepIndex = 0;
  29.             }
  30.         }
  31.         else if (Wizard1.ActiveStepIndex == 2)//当用户进入找回密码第三步
  32.         {
  33.             if (txtPassword.Text != "123456")
  34.             {
  35.                 //用户的找回密码答案正确则修改数据库里的用户登录密码,代码略
  36.             }
  37.             else//如果用户输入的答案不是"123456",则跳转到第二步
  38.             {
  39.                 Wizard1.ActiveStepIndex = 1;
  40.             }
  41.         }
  42.     }
  43. }


这个页面的运行效果如下:
 
在用户名一栏输入“admin”并点击“下一步”按钮的效果:
 
在密码提示答案一栏输入“123456”再点击“下一步”按钮:
 
在新密码和确认新密码中都输入“123456”并点击“完成”按钮。
 
在上面的例子中没有除了验证控件之外,为了简化流程没有使用任何操作数据库的代码。

 

MasterPage母板页
在我们做Web应用的时候,经常会遇到一些页面之间有很多相同的显示部分和行为,如果每个页面都去重复编写这些代码,那就是一件非常麻烦的事情。因此在asp.net2.0中提出了母板页的概念,我们可以把多个页面之间相同的行为和显示部分放到母板页中,只需要为每个页面编写不同的部分即可,这样如果我们对公共部分需要变化仅仅更改母板页就能达到目的。母板页的文件后缀名为.master,一个网站中允许定义多个母板页。
母板页不能单独呈现,也就是我们不能在浏览器中直接输入母板页的url地址进行访问,必须依赖于内容页才能呈现。
下面是新建一个母板页的源代码:


 

  1. <%@ Master Language="C#" AutoEventWireup="true" CodeFile="FrontPage.master.cs" Inherits="FrontPage" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.         <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
  11.         </asp:contentplaceholder>
  12.     </div>
  13.     </form>
  14. </body>
  15. </html>

在母板页中有一个“<asp:contentplaceholder></asp:contentplaceholder>”标记,这相当于一个占位标记,将来使用了这个母板页的内容页中的内容将在这个标记中显示。因为母板页已经包含了<html><head></head><form runat=”server”></form></html>标记,所以内容页中不允许再出现这些标记。
新建一个使用使用当前使用母板页的内容页步骤如下:
(1)在网站项目或者网站项目下的文件夹上点鼠标右键,在出现的右键菜单中选择“添加新项”,出现如下界面:
 
注意:一定要勾选“选择母板页”选项。
(2)点击“添加”按钮,这时会出现选择母板页的界面,如下图:
 
(3)选择正确的母板页,然后点“确定”按钮,这样就完成了添加一个内容页。
这时内容页的代码如下:


 

  1. <%@ Page Language="C#" MasterPageFile="~/FrontPage.master" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" Title="Untitled Page" %>
  2. <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
  3. </asp:Content>

在内容页中有一个<asp:Content></asp:Content>标记,只有放在这个标记之间的代码将来运行时才会可见。
内容页有几个常见属性如下表所示:


属性名说明
Master获取当前内容页所使用的母板页(如果有的话)
MasterPageFile内容所使用的母板页文件的位置
Title内容页的标题
有时候需要访问母板页中的控件,比如母板页上有一个Label控件用于显示当前服务器时间,可以通过获取当前内容页的Master属性来获取所使用的母板页,然后利用母板页的FindControl(string controlId)方法来根据控件的ID查找母板页的控件。
下面是一个内容页访问母板页的例子。
母板页的代码:

  1. <%@ Master Language="C#" AutoEventWireup="true" CodeFile="FrontPage.master.cs" Inherits="FrontPage" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.     <table><tr><td>
  11.         服务器时间:<asp:Label ID="lbServerTime" runat="server" Text=""></asp:Label></td></tr>
  12.     <tr><td>
  13.         <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
  14.         </asp:contentplaceholder>
  15.         </td></tr>
  16.         <tr><td>
  17.             版本号:<asp:Label ID="lbCopyRight" runat="server" Text=""></asp:Label></td></tr>
  18.         </table>
  19.     </div>
  20.     </form>
  21. </body>
  22. </html>

内容页的前台代码:


 

  1. <%@ Page Language="C#" MasterPageFile="~/FrontPage.master" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" Title="内容页访问母板页控件的例子" %>
  2. <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
  3. 内容页的内容放在这里
  4. </asp:Content>

内容页的后台代码:


 

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class MyPage : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.         //其中lbServerTime是母板页上的控件的ID
  16.         Label lbTimer =(Label)(this.Master.FindControl("lbServerTime"));
  17.         lbTimer.Text = DateTime.Now.ToString("yyyy-MM-dd");
  18.         Label lbCopyRight = (Label)(this.Master.FindControl("lbCopyRight"));
  19.         lbCopyRight.Text = "Version 1.0";
  20.     }
  21. }

页面的运行效果:
 


母板页的动态替换
在编程开发中还可以根据条件动态替换内容页所使用的母板页,母板页替换处理要在内容的初始化阶段,也就是在内容页的PreInit事件里。
下面就是一个随即动态替换母板页的例子:


 

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class MyPage : System.Web.UI.Page
  12. {
  13.     //在这里更换母板页,不能在Page_Load事件里更换,会报异常
  14.     protected override void OnPreInit(EventArgs e)
  15.     {
  16.         if (DateTime.Now.Millisecond % 2 == 0)
  17.         {
  18.             //注意"~/MasterPage.master"母板页中必须有当前母板页中一致的控件
  19.             this.MasterPageFile = "~/MasterPage.master";
  20.         }
  21.         base.OnInit(e);
  22.     }
  23. }

总结:本篇讲述了一些比较复杂的网页效果的实现办法,比如类似于WinForm中的选项卡式效果、树形菜单、用于多步骤收集用户信息的向导效果等,还有便于网站统一布局合显示的母板页的使用,并且讲述了如何动态替换母板页。下一篇将讲述web.config的用法和配置。

后记:最近有不少朋友在我的博客http://blog.csdn.net/zhoufoxcn上留言,要求在我原有计划上增加一些新的内容,我会酌情增加一些,但是由于时间不会一一照顾到,敬请谅解。

2008-11-01  01:25完成,2008-11-03 02:30整理
周公(周金桥)

注意,因为个人空间大小和下载速度受限,所以以后不再提供从本人主机上的下载地址,可以到www.verycd.com下载《ASP.NET夜话》的测试版视频教程。地址是:http://www.verycd.com/topics/2730883/

 

Asp.net夜话系列文章:

 

评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周公

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值