当前位置导航:炫浪网>>网络学院>>编程开发>>Visual C#教程

TreeView的动态显示及利用框架实现导航

   在Asp.net中我们知道TreeView控件可以实现站点导航功能,利用模板加上站点地图作为TreeView的DataSource就可以实现轻松的导航功能。我本次所要实现的导航抛开了模板和站点地图,利用框架动态实现导航。

    我们知道,TreeView控件可以静态的预定义其结构,支持的数据源控件有XmlDataSource 和 SiteMapDataSource ,并不支持sqldatasource控件。这次我们的数据源正是数据库,所以我们可以动态的填充TreeView的节点。在实现TreeView的动态填充节点后,我们可以利用iframe框架,来实现导航。

一.对TreeView控件本次所要用到的属性及事件的介绍

1.TreeNode.SelectAction属性:获取或设置选择节点时引发的事件,此属性的值为TreeNodeSelectAction 值之一,默认为TreeNodeSelectAction.Select。TreeView的文本节点可以处于两种模式之一,默认情况下,会有一个节点处于选定状态,即TreeNodeSelectAction.Select,此模式下引发SelectedNodeChanged事件,引发后节点只会展开,不会折叠。若要使一个节点处于导航模式,可以把该节点的 NavigateUrl 属性值设置为空字符串 ("") 以外的值。若要使节点处于选择模式,可以把节点的 NavigateUrl 属性设置为空字符串。

2.TreeNode.PopulateOnDemand属性:该属性只为bool类型,获取或设置一个值,该值指示是否动态填充节点,默认为false。当节点的 PopulateOnDemand 属性设置为 true 时,在运行阶段展开节点时通过回发事件填充节点。若要动态填充节点,必须为 TreeNodePopulate 事件定义填充节点的事件处理方法。

3.TreeNode.TreeNodePopulate事件:当节点的 PopulateOnDemand 属性设置为 true 时,可以触发该事件,以编程的方式动态填充节点。

二.实现TreeView的动态填充节点.

1.由于是获取数据里面的数据,于是写了个SqlHelper类,我前面的一篇文章详细叙述过,里面同样介绍了数据库的关系图,感兴趣的朋友可以参考对DataList控件绑定图片的一点小结 里的部分内容,这里为了不影响阅读,把代码还是贴出来了:

  4.实现TreeView动态填充节点,主要有两个方法:

DALHelper类
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Configuration;
  6using System.Data;
  7using System.Data.SqlClient;
  8namespace DBHelper
  9{
 10    public class DALHelper
 11    {
 12        private static string constr = ConfigurationManager.ConnectionStrings["MyNBAData"].ConnectionString;
 13        private static SqlConnection connection = new SqlConnection(constr);
 14   
 15        /**//// <summary>
 16        /// 检查连接是否打开
 17        /// </summary>
 18        public static bool CheckConnOpen()
 19        {
 20            if (connection == null || connection.State == ConnectionState.Closed)
 21            {
 22                connection.Open();
 23                return true;
 24            }
 25            else
 26            {
 27                return false;
 28            }
 29        }
 30        /**//// <summary>
 31        /// 检查连接是否关闭
 32        /// </summary>
 33        public static bool CheckConnClosed()
 34        {
 35            if (connection != null || connection.State == ConnectionState.Open)
 36            {
 37                connection.Close();
 38                return true;
 39            }
 40            else
 41            {
 42                return false;
 43            }
 44        }
 45
 46        /**//// <summary>
 47        /// 获取一个DataTable
 48        /// </summary>
 49        /// <param name="sql"></param>
 50        /// <returns></returns>
 51        public static DataTable GetDataTable(string sql)
 52        {
 53            SqlDataAdapter da = null;
 54            DataTable dt = null;
 55            try
 56            {
 57                da = new SqlDataAdapter(sql, connection);
 58                dt = new DataTable();
 59                da.Fill(dt);
 60            }
 61            catch (Exception ex)
 62            {
 63
 64                throw new Exception(ex.Message);
 65            }
 66          
 67            return dt;
 68        }
 69
 70     /**//// <summary>
 71     /// 获取DataReader对象
 72     /// </summary>
 73     /// <param name="sql"></param>
 74     /// <param name="parms"></param>
 75     /// <returns></returns>
 76        public static SqlDataReader ExecuteReader(string sql, SqlParameter[] parms)
 77        {
 78            SqlCommand command= null;
 79            SqlDataReader reader = null;
 80            try
 81            {
 82                command = new SqlCommand(sql, connection);
 83                if (parms!=null)
 84                {
 85                    foreach (var item in parms)
 86                    {
 87                        command.Parameters.Add(item);
 88                    }
 89                }
 90                if( CheckConnOpen())
 91                {
 92                    reader = command.ExecuteReader(CommandBehavior.CloseConnection);
 93                }
 94              
 95               
 96            }
 97            catch (Exception ex)
 98            {
 99
100                throw new Exception(ex.Message);
101            }
102            finally
103            {
104               //CheckConnClosed();
105            }
106            return reader;
107        }
108    
109        /**//// <summary>
110        /// 执行数据库的修改,插入,删除
111        /// </summary>
112        /// <param name="sql"></param>
113        /// <param name="parms"></param>
114        /// <returns></returns>
115        public static int ExecuteNonQuery(string sql, SqlParameter[] parms)
116        {
117            SqlCommand command = null;
118            int count = 0;
119            try
120            {
121                command = new SqlCommand(sql, connection);
122                if (parms!=null)
123                {
124                    foreach (var item in parms)
125                    {
126                        command.Parameters.Add(item);
127                    }
128                }
129
130                CheckConnOpen();
131                count = command.ExecuteNonQuery();
132            }
133            catch (Exception ex)
134            {
135
136                throw new Exception(ex.ToString());
137            }
138            finally
139            {
140                CheckConnClosed();
141            }
142            return count;
143        }
144    }
145}
146
 

2.建立了一个页面DynamicPlayer.aspx,页面内容为:

DynamicPlayer.aspx页面内容
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DynamicPlayer.aspx.cs" Inherits="DynamicPlayer" %>

<!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 style="height: 437px; width: 587px">
    <table style="width: 100%">
        <tr style=" height:437px">
        <td style="width:50%; background-color: #CCCCFF; " align="left";  valign="top">
            <asp:TreeView ID="trPlayer" runat="server"
                ontreenodepopulate="trPlayer_TreeNodePopulate"
                 >
                <Nodes>
                    <asp:TreeNode PopulateOnDemand="True" Text="NBA球队" Value="NBA球队"></asp:TreeNode>
                </Nodes>
            </asp:TreeView>
        </td>
        <td style="width:50%" valign="top">
            <div style="border-style: dashed; border-color: #FF00FF; height:423px; width:273px; position: fixed; margin-left: 50px; margin-top: 50px; top: -31px; left: 257px;">
            <iframe  id="myframe"  style="width: 263px; height: 300px" frameborder="1" scrolling="yes" >
           </iframe>
            </div>
        </td>
        </tr>
    </table>
 
    </div>
    </form>
</body>
</html>

 3.实现TreeNode.TreeNodePopulate事件

 

 1  /// <summary>
 2     /// TreeNodePopulate事件,实现动态填充叶节点
 3     /// </summary>
 4     /// <param name="sender"></param>
 5     /// <param name="e"></param>
 6     protected void trPlayer_TreeNodePopulate(object sender, TreeNodeEventArgs e)
 7     {
 8         if (e.Node.ChildNodes.Count==0)
 9         {
10             switch (e.Node.Depth)
11             {
12                 case 0:
13                     BindTeam(e.Node);//填充第一层节点
14                     break;
15                 case 1:
16                     BindPlayer(e.Node);//填充第二层节点
17                     break;
18                 default:
19                     break;
20             }
21         }
22     }
 

  i: BindTeam(TreeNode node),实现第一层节点绑定

 

 1 //第一层节点绑定到数据库表里的Team的球队名字
 2     public void BindTeam(TreeNode node)
 3     {
 4         string sql = "select TeamID,TeamNameCH from Team";
 5         DataTable dt = DBHelper.DALHelper.GetDataTable(sql);
 6         if (dt!=null)
 7         {
 8             foreach (DataRow dr in dt.Rows)
 9             {
10                 TreeNode tn = new TreeNode(Convert.ToString(dr["TeamNameCH"])
11                 , Convert.ToString(dr["TeamID"]));
12                 tn.PopulateOnDemand = true;
13                 tn.SelectAction = TreeNodeSelectAction.Expand;
14                 node.ChildNodes.Add(tn);
15             }
16         }
17     }
ii:BindPlayer(TreeNode node):实现第二层节点绑定:

 1 //第二层节点绑定到数据库表里的Player的球员名字
 2     public void BindPlayer(TreeNode node)
 3     {
 4         string sql= "select PlayerID,NameCH from Player where TeamID='{0}'";
 5         sql = string.Format(sql, node.Value);
 6         DataTable dt =DBHelper.DALHelper.GetDataTable(sql);
 7         if (dt != null)
 8         {
 9             foreach (DataRow dr in dt.Rows)
10             {
11               
12                 TreeNode tn = new TreeNode(Convert.ToString(dr["NameCH"]), Convert.ToString(dr["PlayerID"]));
13                 tn.PopulateOnDemand = false;//设为FALSE时不会在去填充下一级节点
14
15                 //设为select模式可以实现导航,需设置NavigateUrl属性,由于本次实现的
16                 //是框架内的导航模式,所以NavigateUrl的值为空
17                 tn.SelectAction = TreeNodeSelectAction.Select;
18               //  tn.NavigateUrl = "ShowPlayerImage.aspx?PlayerID=" + playerID;
19                 tn.Target = "myframe";
20                 node.ChildNodes.Add(tn);
21             }
22         }
23     }
三.实现当单击叶节点即是点击球员姓名时在iframe中导航至一个已经写好了的专门用来显示球员相片的的页面

1.显示球员相片的的页面为ShowPlayerImage.aspx。

页面内容为:

ShowPlayerImage.aspx页面内容
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ShowPlayerImage.aspx.cs" Inherits="ShowPlayerImage" %>

<!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>照片显示</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
   
    </div>
    </form>
</body>
</html>
后台代码为:

ShowPlayerImage.aspx后台代码
  1using System;
  2using System.Collections;
  3using System.Configuration;
  4using System.Data;
  5using System.Linq;
  6using System.Web;
  7using System.Web.Security;
  8using System.Web.UI;
  9using System.Web.UI.HtmlControls;
 10using System.Web.UI.WebControls;
 11using System.Web.UI.WebControls.WebParts;
 12using System.Xml.Linq;
 13using System.IO;
 14using System.Data.SqlClient;
 15public partial class ShowPlayerImage : System.Web.UI.Page
 16{
 17    protected void Page_Load(object sender, EventArgs e)
 18    {
 19        if (!IsPostBack)
 20        {
 21            int playerID = Convert.ToInt32(Request.QueryString["PlayerID"]);
 22            byte[] bytes = BindImage(playerID);
 23
 24            Response.Clear();
 25            if (bytes != null)
 26            {
 27                Response.BinaryWrite(bytes);
 28            }
 29            else
 30            {
 31                Response.BinaryWrite(LoadUnknowImage());
 32            }
 33            Response.End();
 34        }
 35    }
 36   
 37    /**//// <summary>
 38    /// 绑定数据库中的球员相片
 39    /// </summary>
 40    /// <param name="playerID">该参数是用来接收DataList.aspx页面传过来的球员ID</param>
 41    /// <returns></returns>
 42    public byte[] BindImage(int playerID)
 43    {
 44        string sql = "select Photo from Player where PlayerID=@PlayerID";
 45        SqlDataReader reader = null;
 46        byte[] photoBytes=null;
 47        try
 48        {
 49            SqlParameter parm = new SqlParameter("@PlayerID", SqlDbType.Int);
 50            parm.Value = playerID;
 51            reader = DBHelper.DALHelper.ExecuteReader(sql, new SqlParameter[] {parm});
 52            if (reader!=null)
 53            {
 54                 while (reader.Read())
 55                    {
 56                        if (!(reader["Photo"] is DBNull))
 57                        {
 58                            photoBytes = (byte[])reader.GetSqlBinary(0);
 59                        }
 60                    }
 61            }
 62          
 63
 64        }
 65        finally
 66        {
 67            if (reader!=null)
 68            {
 69                reader.Close();
 70            }
 71           
 72       
 73        }
 74        return photoBytes;
 75    }
 76
 77    /**//// <summary>
 78    /// 当未能从数据中取得相片时我们用一张事先准备好的图片来替代,该图片在网站的App_Themes的文件夹下
 79    /// </summary>
 80    /// <returns></returns>
 81    public byte[] LoadUnknowImage()
 82    {
 83        byte[] bytes = null;
 84        FileStream fs = null;
 85        BinaryReader readBytes = null;
 86        try
 87        {
 88            fs = new FileStream(Server.MapPath("~/App_Themes/Pictures/unknow.jpg?http://www.xvna.com"), FileMode.Open, FileAccess.Read);
 89            readBytes = new BinaryReader(fs);
 90            bytes = readBytes.ReadBytes(Convert.ToInt32(fs.Length));
 91        }
 92        catch (Exception ex)
 93        {
 94
 95            throw new Exception(ex.Message);
 96        }
 97        finally
 98        {
 99            readBytes.Close();
100            fs.Close();
101        }
102        return bytes;
103    }
104}
105
2.由于TreeNode里的两事件TreeNodeCollapsed(当节点折叠后触发),TreeNodeExpanded(节点展开后触发)都没有实现导航功能所想要的事件,于是自己自定义了一个关于TreeView的节点单击事所要触发的事件TreeNodeOnClick,每当单击叶节点时都会触发该事件,并导航到显示相片的页面。

自定义事件的代码为:

 1  //自定义TreeNodeOnClickHandler委托
 2     public delegate void TreeNodeOnClickHandler(object sender, TreeNodeEventArgs e);
 3     //自定义TreeNodeOnClick事件,每当鼠标单击节点时触发该事件
 4     public event TreeNodeOnClickHandler TreeNodeOnClick;
 5  /// <summary>
 6     ///单击叶节点事件, 实现动态导航
 7     /// </summary>
 8     /// <param name="sender"></param>
 9     /// <param name="e"></param>
10     protected void DynamicPlayer_TreeNodeOnClick(object sender, TreeNodeEventArgs e)
11     {
12         string src = "";
13         string playerID = "";
14         if (e.Node.ChildNodes.Count == 0 && e.Node.Depth == 2)
15         {
16             playerID = e.Node.Value;
17             src = "ShowPlayerImage.aspx?PlayerID=" + playerID;
18             //把iframe的属性src会发给客户端时赋给一个hidden
19             Page.ClientScript.RegisterHiddenField("srcHidden", src);
20             //注册客户端脚本,给iframe的属性src赋值,这样就可以在框架内导航到另外一个页面
21             Page.ClientScript.RegisterStartupScript(this.GetType(), "registFrameAttribute",
22                 "var frame=document.getElementById('myframe');frame.src=document.getElementById('srcHidden').value;",true);
23         }
24     }
3.每次我们单击叶节点会向服务器回发,此时就可以实现导航,代码为:

 1  protected void Page_Load(object sender, EventArgs e)
 2     {
 3         //每次单击节点时回发
 4         if (IsPostBack)
 5         {
 6             //注册事件
 7              this.TreeNodeOnClick += new TreeNodeOnClickHandler(DynamicPlayer_TreeNodeOnClick);
 8             //如果是叶节点并且被选中事,触发自定义的TreeView的Click事件
 9              if (trPlayer.SelectedNode.Selected&&trPlayer.SelectedNode.ChildNodes.Count==0)
10              {
11                  TreeNodeOnClick(this, new TreeNodeEventArgs(trPlayer.SelectedNode));
12              }
13         }
14       
15     }
这样就简单实现了我说的全部功能,运行后效果为:

 

相关内容
赞助商链接