原来我的数据库中的结构是这样的:
class表:C_id ParentsId C_class
1 0 软件工程
2 0 网络编程
3 0 C#程序设计
4 1 第一章
5 1 第二章
6 2 第一章
7 2 第二章
8 2 第三章
9 3 第一章
10 3 第二章用TreeView控件绑定 想使之效果为:第一级节点显示课程的名称 然后他们下面可以展开他们的章节,比如软件工程有 第一章 第二章 ;网络编程有 第一章 第二章 第三章 。上面这样的数据库结构配合下面的程序,可以实现这个效果。
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
string SqlConn=System.Configuration.ConfigurationSettings.AppSettings["ConnString"];
Conn=new SqlConnection(SqlConn);
CreateDataSet();
InitTree(this.TreeView1.Nodes,"0");
}
private DataSet CreateDataSet()
{
SqlStr="select * from class";
da=new SqlDataAdapter(SqlStr,Conn);
data=new DataSet();
da.Fill(data,"tree");
return data;
}
private void InitTree(TreeNodeCollection Nds,string parentId)
{
TreeNode tmpNd;
DataRow[] rows=data.Tables[0].Select("ParentId='"+parentId+"'");
foreach(DataRow row in rows)
{
tmpNd=new TreeNode();
tmpNd.ID=row["C_id"].ToString();
tmpNd.Text=row["C_class"].ToString();
tmpNd.NavigateUrl="index.aspx?class="+row["parentId"].ToString()+"&C_id="+row["C_id"].ToString();
Nds.Add(tmpNd);
InitTree(tmpNd.Nodes,tmpNd.ID);
}
}
这样做主要思想是,先从表里找出根节点的数据,然后生成TreeNode节点插入到TreeView中,然后用第归寻找当前节点的子节点,生成TreeNode并插入到TreeView中。这样做是可以的。
但我想从新设计一下数据库,让它更容易理解些。我想做成这样:
C_id NodeId C_class
1 第一章 软件工程
2 第二章 软件工程
3 第三章 软件工程
4 第一章 C#程序设计
5 第二章 C#程序设计
6 第三章 C#程序设计
7 第一章 网络编程
8 第二章 网络编程现在想这样做数据库或者需要再加一些节点(比如ParentId),来达到同样的效果,也就是第一级级节点显示课程名称 然后他们有多少章节 就可以展开看到。
基本就是这样,我想了一天,高手们,帮我指点一下。我现在主要困惑的问题是,怎么样插入课程的章节到它所在的课程名称节点下!
class表:C_id ParentsId C_class
1 0 软件工程
2 0 网络编程
3 0 C#程序设计
4 1 第一章
5 1 第二章
6 2 第一章
7 2 第二章
8 2 第三章
9 3 第一章
10 3 第二章用TreeView控件绑定 想使之效果为:第一级节点显示课程的名称 然后他们下面可以展开他们的章节,比如软件工程有 第一章 第二章 ;网络编程有 第一章 第二章 第三章 。上面这样的数据库结构配合下面的程序,可以实现这个效果。
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
string SqlConn=System.Configuration.ConfigurationSettings.AppSettings["ConnString"];
Conn=new SqlConnection(SqlConn);
CreateDataSet();
InitTree(this.TreeView1.Nodes,"0");
}
private DataSet CreateDataSet()
{
SqlStr="select * from class";
da=new SqlDataAdapter(SqlStr,Conn);
data=new DataSet();
da.Fill(data,"tree");
return data;
}
private void InitTree(TreeNodeCollection Nds,string parentId)
{
TreeNode tmpNd;
DataRow[] rows=data.Tables[0].Select("ParentId='"+parentId+"'");
foreach(DataRow row in rows)
{
tmpNd=new TreeNode();
tmpNd.ID=row["C_id"].ToString();
tmpNd.Text=row["C_class"].ToString();
tmpNd.NavigateUrl="index.aspx?class="+row["parentId"].ToString()+"&C_id="+row["C_id"].ToString();
Nds.Add(tmpNd);
InitTree(tmpNd.Nodes,tmpNd.ID);
}
}
这样做主要思想是,先从表里找出根节点的数据,然后生成TreeNode节点插入到TreeView中,然后用第归寻找当前节点的子节点,生成TreeNode并插入到TreeView中。这样做是可以的。
但我想从新设计一下数据库,让它更容易理解些。我想做成这样:
C_id NodeId C_class
1 第一章 软件工程
2 第二章 软件工程
3 第三章 软件工程
4 第一章 C#程序设计
5 第二章 C#程序设计
6 第三章 C#程序设计
7 第一章 网络编程
8 第二章 网络编程现在想这样做数据库或者需要再加一些节点(比如ParentId),来达到同样的效果,也就是第一级级节点显示课程名称 然后他们有多少章节 就可以展开看到。
基本就是这样,我想了一天,高手们,帮我指点一下。我现在主要困惑的问题是,怎么样插入课程的章节到它所在的课程名称节点下!
解决方案 »
- 在线使用FreeTextBox编辑器时,打空格的时候出现乱码!
- windows 7 x64 安装Oracle 10g 无法解析指定的连接标识符 错误
- 问个非常非常简单的问题,呵呵。
- 请教关于新浪网上的问题
- DataAdapter.Update()不起作用。。。
- 超链接连接不过去
- ueditor 生成html页面,并且在目录下生成html文件
- 上传文件如何解除限制?怪~!
- 请高手帮忙!
- saucer and qiushuiwuhen(秋水无恨)请进,接着问:把日历中取来的休息日存进库中,表中只有一个holiday的字段,没有关键字,如何使表中保
- 点击删除时要求弹出一个删除确认框为什么只能第二次时才可以弹出呢??
- 安全性异常 急~
http://www.why100000.com/_articles/show_a_article.asp?autoid=36&tab=tabAspNet
http://www.addtoo.net/Visitor/View.aspx
数据库树形结构我参考的是这篇文章:
http://www.sitepoint.com/article/hierarchical-data-database/2
/// 生成树
/// </summary>
/// <param name="iUserID">用户ID</param>
/// <param name="trvMenu">菜单Tree</param>
/// <param name="iMenuID">菜单ID</param>
/// <param name="iMenuRightCount">有权限的数目</param>
public void GenerateTree(int iUserID, TreeView trvMenu, int iMenuID, out int iMenuRightCount)
{
iMenuRightCount = 0;
DataGroup dgAllMenus = this.GetUserMenus(iUserID); if ( dgAllMenus == null ) //如果查询时出现错误, 只添加退出菜单 {
TreeNode rootNode = new TreeNode();
rootNode.Text = "退出";
rootNode.NodeData = "";
rootNode.Expanded = true;
trvMenu.Nodes.Add(rootNode); TreeNode nodLoginAgain = new TreeNode();
nodLoginAgain.Text = "重新登录";
nodLoginAgain.NodeData = "";
nodLoginAgain.NavigateUrl = "Login.aspx?Type=LoginAgain";
rootNode.Nodes.Add(nodLoginAgain); TreeNode nodQuit = new TreeNode();
nodQuit.Text = "<div onclick='window.close();'>退出系统</div>";
nodQuit.NodeData = "";
rootNode.Nodes.Add(nodQuit); return;
} //获取一级菜单
DataView dvRootMenu = new DataView(dgAllMenus.Table, "MenuLevel = 1", "DisplayNo", DataViewRowState.CurrentRows);
if (dvRootMenu.Count == 0) //没有权限,只显示退出
{
iMenuRightCount = 0;
TreeNode rootNode = new TreeNode();
rootNode.Text = "退出";
rootNode.NodeData = "";
rootNode.Expanded = true;
trvMenu.Nodes.Add(rootNode); TreeNode nodLoginAgain = new TreeNode();
nodLoginAgain.Text = "重新登录";
nodLoginAgain.NodeData = "";
nodLoginAgain.NavigateUrl = "Login.aspx?Type=LoginAgain";
rootNode.Nodes.Add(nodLoginAgain); TreeNode nodQuit = new TreeNode();
nodQuit.Text = "<div onclick='window.close();'>退出系统</div>";
nodQuit.NodeData = "";
rootNode.Nodes.Add(nodQuit);
}
else //有权限
{
iMenuRightCount = 1; string[] strMenuIDPath = this.GetMenuIDPath(iMenuID); //Get Menu ID Path
string strNodeIndex = ""; for (int i=0; i<dvRootMenu.Count; i++)
{
//添加一级菜单
TreeNode firstNode = new TreeNode();
firstNode.Text = dvRootMenu[i]["MenuName"].ToString();
firstNode.NodeData = dvRootMenu[i]["MenuID"].ToString();
firstNode.Expanded = true;
trvMenu.Nodes.Add(firstNode); if (strMenuIDPath[0] != "-1")
{
for (int j=0; j<strMenuIDPath.Length; j++)
{
if (strMenuIDPath[j] == firstNode.NodeData)
{
strNodeIndex = i.ToString();
break;
}
}
}
this.CreateNode(Int32.Parse(dvRootMenu[i]["MenuID"].ToString()), 2, firstNode, dgAllMenus.Table, strMenuIDPath, ref strNodeIndex);
} TreeNode rootNode = new TreeNode();
rootNode.Text = "退出";
rootNode.NodeData = "";
rootNode.Expanded = true;
trvMenu.Nodes.Add(rootNode); TreeNode nodLoginAgain = new TreeNode();
nodLoginAgain.Text = "重新登录";
nodLoginAgain.NodeData = "";
nodLoginAgain.NavigateUrl = "Login.aspx?Type=LoginAgain";
rootNode.Nodes.Add(nodLoginAgain); TreeNode nodQuit = new TreeNode();
nodQuit.Text = "<div onclick='window.close();'>退出系统</div>";
nodQuit.NodeData = "";
rootNode.Nodes.Add(nodQuit); if (strMenuIDPath[0] != "-1")
{
try
{
trvMenu.SelectedNodeIndex = strNodeIndex;
}
catch
{
}
}
}
} /// <summary>
/// 循环生成树的结构
/// </summary>
/// <param name="fatherID">上一级菜单ID</param>
/// <param name="menuLevel">菜单级数</param>
/// <param name="parentNode">上一级的Node</param>
/// <param name="dtMenu">DataTable</param>
/// <param name="strMenuIDPath">Menu ID Path</param>
/// <param name="strNodeIndex">Node Index</param>
private void CreateNode(int fatherID, int menuLevel, TreeNode parentNode, DataTable dtMenu, string[] strMenuIDPath, ref string strNodeIndex)
{
DataRow[] drMenu = dtMenu.Select("FatherID = " + fatherID + " AND MenuLevel = " + menuLevel, "DisplayNo");
int intIndex = 0;
foreach (DataRow dr in drMenu)
{
TreeNode curNode = new TreeNode();
curNode.Text = dr["MenuName"].ToString();
curNode.NodeData = dr["MenuID"].ToString(); if (dr["MenuPath"].ToString() != "")
{
curNode.NavigateUrl = dr["MenuPath"].ToString();
curNode.Target = "MainFrame";
} if (strMenuIDPath[0] != "-1")
{
for (int i=0; i<strMenuIDPath.Length; i++)
{
if (strMenuIDPath[i] == curNode.NodeData)
{
strNodeIndex += "." + intIndex.ToString();
curNode.Expanded = true;
break;
}
}
} parentNode.Nodes.Add(curNode); //添加下一级的菜单
CreateNode(Int32.Parse(dr["MenuID"].ToString()), menuLevel+1, curNode, dtMenu, strMenuIDPath, ref strNodeIndex); intIndex++;
}
}
/// <summary>
/// 绑定父节点
/// </summary>
private void Bindclass()
{
class[] _m = Getclass();//实体类class。(属性说明自动提取数据库字段的描述信息)具体写法后面有
foreach (class _l in _m)
{
// 循环生成根节点
TreeNode n = new TreeNode(_l.mod_name);
n.ToolTip = _l.mod_name;
n.Value = _l.mod_id.ToString();
n.SelectAction = TreeNodeSelectAction.None;
tmpNd.Nodes.Add(n);
CreateNode(n, _l);
}
} /// <summary>
/// 递归生成所有子节点
/// </summary>
/// <param name="p_Node">节点</param>
/// <param name="p_class">模块</param>
private void CreateNode(TreeNode p_Node, class p_class)
{
class[] _m = GetChildclass(p_class);
foreach (class _l in _m)
{
TreeNode n = new TreeNode(_l.mod_name);
n.ToolTip = _l.mod_name;
n.Value = _l.mod_id.ToString();
n.SelectAction = TreeNodeSelectAction.None;
p_Node.ChildNodes.Add(n);
CreateNode(n, _l);
}
} /// <summary>
/// 获取所有父模块
/// </summary>
/// <returns></returns>
public class[] Getclass()
{
string SQL = "select C_id from class where (ParentsId = '0') ";
return GetclassBySQL(SQL);
} /// <summary>
/// 获取父模块下的子模块
/// </summary>
/// <param name="p_class">父模块</param>
/// <returns></returns>
public class[] GetChildclass(class p_class)
{
if (p_class != null && p_class.C_id.ToString() != string.Empty)
{
string SQL = "select C_id from class where ParentsId = '" + p_class.C_id + "' ";
return GetclassBySQL(SQL);
}
return new class[0];
} /// <summary>
/// 获取模块数组
/// </summary>
/// <param name="p_SQL">SQL 语句</param>
/// <returns></returns>
private class [] GetclassBySQL(string p_SQL)
{
ArrayList _a = new ArrayList();
DataTable objData = ado.GetDataTable(p_SQL);//此处就是获取一个datatable ,ado是我自己的数据库链接的类库
for (int i = 0; i < objData.Rows.Count; i++)
{
_a.Add(GetclassByID(objData.Rows[i]["C_id"].ToString()));
}
objData.Dispose();
objData = null;
return (class[])_a.ToArray(typeof(class));
} /// <summary>
/// 获取一个class对象
/// </summary>
/// <param name="p_classID">classID</param>
/// <returns></returns>
public class GetclassByID(string p_classID)
{
if (p_classID != string.Empty)
{
class m = new class();
string sql = "select * from class where (C_id = '"+p_classID+"') ";
DataTable objData = ado.GetDataTable(sql);//此处同样也是获取一个datatable
if (objData.Rows.Count > 0)
{
m.C_id= int.Parse(objData.Rows[0]["C_id"].ToString());
m.ParentsId= int.Parse(objData.Rows[0]["ParentsId"].ToString());
m.C_class = objData.Rows[0]["C_class"].ToString();
}
objData.Dispose();
objData = null;
return m;
}
else
return (new class());
}下面是实体类class的写法
/// <summary>
/// 实体类class。(属性说明自动提取数据库字段的描述信息)
/// </summary>
public class class
{
public class()
{ }
private int _C_id;
private int _ParentsId;
private string _C_class; /// <summary>
///
/// </summary>
public int C_id
{
set { _C_id= value; }
get { return _C_id; }
}
/// <summary>
///
/// </summary>
public int ParentsId
{
set { _ParentsId = value; }
get { return _ParentsId; }
}
/// <summary>
///
/// </summary>
public string C_class
{
set { _C_class = value; }
get { return _C_class; }
}
}
看看这个http://www.51aspx.com/CV/AjaxNodeTree/