控件下载地址 http://d.download.csdn.net/down/1059698/chenguang79
这里只说明一下我在使用中的一些方法。只是做为个人记录。如有不当之处,请朋友给与指出,本人万分感谢
个人感觉FlyTreeView这个树控件是现在所有树控件中比较好的一种,在做一些项目中全都使用了此树。下面我将我的一些使用介绍一下。一是为自己做一个记录,二是希望能帮助一些初用的朋友。
这里我用一个简单的例子,就是学校教研组与老师的关系,我这里有二个表,一个表用来存入一个学校有哪些教研组,另一个表用来存放老师的信息。它们是通过Dept_ID字段进行关联的
在这里,我完成的功能是这样的,树结构是分层获得并且加上了复选框。我这里的分层是,你点击树上哪个根结点它就把它对应的子结点信息从数据库中取出,并展开,显示出来。这种方法,对于一颗比较大的树来说是很好用的。
下面是我的代码。
前台代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TempTeacherTree.aspx.cs" Inherits="ClassOnLineSms.TempTeacherTree" %> <%@ Register assembly="NineRays.WebControls.FlyTreeView" namespace="NineRays.WebControls" tagprefix="NineRays" %> <!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> <mce:script type="text/javascript"><!-- //这里的代码,是此控件操作复选择框的,主要作用是当父结点被选择时,子结点根着对应变化 var ignoreEvents = false; function nodeEventHandler(treeview, node, eventType) { if (ignoreEvents) return; ignoreEvents = true; if (eventType == "checked") { setChildrenCheckBox(node, true); if (allSiblingChecked(node)) { setParentCheckBox(node, true); } } else if (eventType == "unchecked") { setChildrenCheckBox(node, false); setParentCheckBox(node, false); } ignoreEvents = false; } function setChildrenCheckBox(parentNode, value) { var childNodes = parentNode.getChildNodes(); for (var i = 0; i < childNodes.length; i++) { var node = childNodes[i]; node.setChecked(value); setChildrenCheckBox(node, value); } } function setParentCheckBox(node, value) { var parentNode = node.getParent(); if (parentNode == null) return; parentNode.setChecked(value); if (!value || allSiblingChecked(parentNode)) setParentCheckBox(parentNode, value); } function allSiblingChecked(node) { var nodes = node.getSiblingNodes(); for (var i = 0; i < nodes.length; i++) { if (!nodes[i].getChecked()) return false; } return true; } // --></mce:script> </head> <body> <form id="form1" runat="server"> <div> <!-- 这里对于一些方法说明一下 OnNodeEventJavascript 主要是就是关于结点的一些调用 javascript的方法,与上面的代码相对应,我现在主要用的就是它的复选框功能 IsCheckbox (值为true,false)用来表示,树上是否显示复选框 OnPopulateNodes 当我点击结点的时候,它进行的操作,在这里我主要做的就是根据父结点来取得子结点 其它的方法在这时感觉还没有用到 --> <NineRays:FlyTreeView ID="FlyTreeView1" runat="server" BackColor="White" ImageSet="WinXP" OnPopulateNodes="FlyTreeView1_PopulateNodes" BorderColor="Silver" BorderWidth="0px" CssClass="treeMenu" Padding="2px" WideCell="True" IsCheckbox="true" PostBackOnExpand="false" OnNodeEventJavascript="nodeEventHandler" PostBackOnSelect="false" DisplayBar="True" > <DefaultStyle Font-Names="Tahoma" Font-Size="11px" ForeColor="Black" ImageUrl="Images/fff.gif" Padding="1px;3px;3px;1px" RowHeight="16px" /> <SelectedStyle BackColor="65, 86, 122" BorderColor="40, 40, 40" BorderStyle="Solid" BorderWidth="1px" ForeColor="White" Padding="0px;2px;2px;0px" ImageUrl="Images/sss.gif" /> <HoverStyle Font-Underline="True" /> <SelectedHoverStyle BorderStyle="NotSet"></SelectedHoverStyle> </NineRays:FlyTreeView> <mce:script type="text/javascript"><!-- var getTreeContain = document.getElementById("<%=FlyTreeView1.ClientID %>"); getTreeContain.style.overflow = ""; // --></mce:script> </div> <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" /> </form> </body> </html>
后台代码
using System; using System.Collections.Generic; using System.Linq; using System.Data; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace ClassOnLineSms { public partial class TempTeacherTree : System.Web.UI.Page { //这里是一个学校的标识字段 public string schoolcode = "hrbyl"; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { //通过学校的唯一标识,来取得学校有哪些教研组 string strsql = "select * from School_Dept WHERE SchoolCode='" + schoolcode + "'"; //下面这个方法,是我自己写的,你可以采用你自己的方法,主要就是把所得到的值存入dataTable DataTable dt = DataBaseClass.ExecuteDataSetReader(DataBaseClass.DataBaseConn, CommandType.Text, strsql).Tables[0]; foreach (DataRow row in dt.Rows) { AddChild(null, row); } } } //这里是通过得到的数据进行给值的方法,因为我是用到了二个表,里面的字段不一样,哪果你的树表是一个表里面是字段一样,哪么你就可以嵌套的使用这个方法 private void AddChild(NineRays.WebControls.FlyTreeNode fnode, DataRow row) { NineRays.WebControls.FlyTreeNode node = new NineRays.WebControls.FlyTreeNode(row["dept_name"].ToString()); //通过学校code与教研组id取得老师 string strsql = "select * from Teachers where SchoolCode='" + schoolcode + "' and Dept_ID='" + row["dept_id"] + "'"; DataTable tabChild = DataBaseClass.ExecuteDataSetReader(DataBaseClass.DataBaseConn, CommandType.Text, strsql).Tables[0]; if (tabChild.Rows.Count > 0) { //这个属性是用来显示结点前面是否有+号的 node.PopulateNodesOnDemand = true; } else { node.PopulateNodesOnDemand = false; } node.Text = row["dept_name"].ToString(); node.Value = row["dept_id"].ToString(); if (fnode != null) { fnode.ChildNodes.Add(node); } else { this.FlyTreeView1.Nodes.Add(node); } } //当用户点击结点时,触发的事件 protected void FlyTreeView1_PopulateNodes(object sender, NineRays.WebControls.FlyTreeNodeEventArgs e) { //Response.Write("aaaa"+e.Node.Value.ToString()); if (e.Node.ChildNodes.Count <= 0) { string strsql = "select * from Teachers where SchoolCode='" + schoolcode + "' and Dept_ID='" + e.Node.Value.ToString() + "'"; DataTable tabChild = DataBaseClass.ExecuteDataSetReader(DataBaseClass.DataBaseConn, CommandType.Text, strsql).Tables[0]; if (tabChild.Rows.Count > 0) { foreach (DataRow r in tabChild.Rows) { NineRays.WebControls.FlyTreeNode node = new NineRays.WebControls.FlyTreeNode(e.Node.Text); node.Text = r["teach_name"].ToString(); node.Value = r["teach_mob"].ToString(); e.Node.ChildNodes.Add(node); } } } //这里的方法是如果点选了其中的一个父结点,它的子结点也应该被选中 if (e.Node.Checked) { foreach (NineRays.WebControls.FlyTreeNode fn in e.Node.ChildNodes) { fn.Checked = true; } } } protected void Button1_Click(object sender, EventArgs e) { string strTemp = ""; foreach (NineRays.WebControls.FlyTreeNode node in this.FlyTreeView1.Nodes) { //if (node.Checked == true) //{ // strTemp += node.Value.ToString() + "---"; foreach (NineRays.WebControls.FlyTreeNode Cnode in node.ChildNodes) { if (Cnode.Checked == true) { strTemp += Cnode.Value.ToString() + ","; } } //} } Response.Write(strTemp.Substring(0,strTemp.Length-1)); } } }
node.Expanded是用来在一加载时就把所有树全展开
上面的例子做一些简单的已经可以,可是如果我们要的树是一个多层,而是在一个表中怎么呢。现在很多菜单表设置全是一个表,只不过采用一个parentsID这样的字段来分出层了。下面的例子就是这样的一个
这个表与上面的表不一样。是一个菜单的显示。在程序中,我只是把一些用到的字段说明一下,
ID parentID fun_id fun_name
1433 -1 92 我的公文包
1434 1433 9201 公告管理
1435 1433 9202 公文流转
1436 1435 920201 文件类型
1437 1435 920202 文件头
1438 1435 920203 显示设置
1439 1435 920204 增加电子印章
我给出了这个简单的列表,我想大家也能明白,各个字段的意思了吧
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ClassOnLineSms.NewsManage
{
public partial class NewTree : System.Web.UI.Page
{
//标识字段
public string user_flag = "O";
public int i = 2;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//根节点第一层,这里要注意一点的,在这里显示的一定是第一层的信息
string strsql = "select *,len(fun_ID) as fun_Len from menu_fun where len(fun_ID)=" + i + " and fun_Flag='" + user_flag + "' order by fun_ID";
//Response.Write(strsql);
//把所得到的值存入DataTable
DataTable dt = DataBaseClass.ExecuteDataSetReader(DataBaseClass.DataBaseConn, CommandType.Text, strsql).Tables[0];
foreach (DataRow row in dt.Rows)
{
AddChild(null, row);
}
}
}
//这里是通过得到的数据进行给值的方法,
private void AddChild(NineRays.WebControls.FlyTreeNode fnode, DataRow row)
{
NineRays.WebControls.FlyTreeNode node = new NineRays.WebControls.FlyTreeNode(row["fun_ID"].ToString());
//看了我给的字段内容,大家也明白了。我这里每二位就是一层,所以我要在里显示下一层的话,就要加二位了
int j = int.Parse(System.Convert.ToString(row["fun_Len"]))+2;
string strsql = "select *,len(fun_ID) as fun_Len from menu_fun where len(fun_ID)=" + j + " and fun_Flag='" + user_flag + "' and fun_ID like '" + row["fun_ID"] + "%' and fun_ID <> '" + row["fun_ID"] + "' order by fun_ID";
//Response.Write(strsql);
DataTable tabChild = DataBaseClass.ExecuteDataSetReader(DataBaseClass.DataBaseConn, CommandType.Text, strsql).Tables[0];
node.Text = row["fun_name"].ToString();
node.Value = row["fun_ID"].ToString();
if (fnode != null)
{
fnode.ChildNodes.Add(node);
}
else
{
this.FlyTreeView1.Nodes.Add(node);
}
//这里是我们要注意的,这里与上面的例子不同的地方在于,这个判断是否有子结点的判断放到了下面
if (tabChild.Rows.Count > 0)
{
//检查每一个子结点,然后递归调用此方法。以达到多层的效果
for (int i = 0; i < tabChild.Rows.Count; i++)
{
//这个属性是用来显示结点前面是否有+号的
node.PopulateNodesOnDemand = true;
AddChild(node, tabChild.Rows[i]);
}
}
else
{
node.PopulateNodesOnDemand = false;
}
}
//当用户点击结点时,触发的事件
protected void FlyTreeView1_PopulateNodes(object sender, NineRays.WebControls.FlyTreeNodeEventArgs e)
{
//Response.Write("aaaa"+e.Node.Value.ToString());
if (e.Node.ChildNodes.Count <= 0)
{
string strsql = "select * from menu_fun where fun_Flag='" + user_flag + "' and fun_ID like '" + e.Node.Value.ToString() + "%' and fun_ID <> '" + e.Node.Value.ToString() + "' order by fun_ID";
//Response.Write(strsql);
DataTable tabChild = DataBaseClass.ExecuteDataSetReader(DataBaseClass.DataBaseConn, CommandType.Text, strsql).Tables[0];
if (tabChild.Rows.Count > 0)
{
foreach (DataRow r in tabChild.Rows)
{
NineRays.WebControls.FlyTreeNode node = new NineRays.WebControls.FlyTreeNode(e.Node.Text);
node.Text = r["fun_name"].ToString();
node.Value = r["fun_ID"].ToString();
e.Node.ChildNodes.Add(node);
}
}
}
//这里的方法是如果点选了其中的一个父结点,它的子结点也应该被选中
if (e.Node.Checked)
{
foreach (NineRays.WebControls.FlyTreeNode fn in e.Node.ChildNodes)
{
fn.Checked = true;
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
string strTemp = "";
foreach (NineRays.WebControls.FlyTreeNode node in this.FlyTreeView1.Nodes)
{
//if (node.Checked == true)
//{
// strTemp += node.Value.ToString() + "---";
foreach (NineRays.WebControls.FlyTreeNode Cnode in node.ChildNodes)
{
if (Cnode.Checked == true)
{
strTemp += Cnode.Value.ToString() + ",";
}
}
//}
}
Response.Write(strTemp.Substring(0,strTemp.Length-1));
}
}
}