C#中的树很多。比如,Windows Form程序设计和Web程序设计中都有一种被称为TreeView的控件。TreeView控件是一个显示树形结构的控件,此树形结构与Windows资源管理器中的树形结构非常类似。不同的是,TreeView可以由任意多个节点对象组成。每个节点对象都可以关联文本和图像。另外,Web程序设计中的TreeView的节点还可以显示为超链接并与某个URL相关联。每个节点还可以包括任意多个子节点对象。包含节点及其子节点的层次结构构成了TreeView控件所呈现的树形结构。
下面是很典型的一个例子,就是用TreeView绑定数据。数据一般符合树形结构,如行政区域之间的关系、公司部门与部门员工之间关系、磁盘目录文件之间的关系等。
父级与子级之间满足一对多的关系,因此在数据库设计中常用一字段来做本表主键的外键,代表父级区域ID。当然,如果要方便求子孙的算法(例如列举武汉所有子区域)可以另加一字段,记录从根结点到当前结点所经历的结点ID。
思路分析:
1. 获取表Area中的所有数据,存放到DataTable中。
2. 获取根结点的数据并添加到根节点。根结点的处理常与子结点的递归处理不一样,例如根结点的添加是在treeView1.Nodes.Add里面,而子结点递归是在父结点上添加,因此经常要分开处理。获取根结点数据可用DataTable.Select(“fAreaId=-1”)来获取。绑定结点时,将Node.Text设为区域的名字,Node.Tag设为区域对应的数据行DataRow或者区域的ID,这样遍历子区域就知道父结点区域信息,也方便应用程序获取选中的结点对应的数据。
3. 递归遍历子区域并添加到TreeView控件中。递归方法参数为Node,由父级Node.Tag就能获取父级区域数据信息,进而获取其子区域,获取子区域可用
DataRow[] rows=DataTable.Select(“fAreaId=”+父级区域ID)。获取子区域后将其获取的信息绑定到新建的Node对象,方法同第二步,然后递归调用自己。当区域不包含任何子区域时,递归终止,即rows.Length==0.
代码如下:
public partial class BindAreaForm : Form
{
private DataTable dt = null ;
public BindAreaForm()
{
InitializeComponent();
InitDataTable();
}
// 获取Area所用数据
private void InitDataTable()
{
SqlConnection conn = new SqlConnection( " Data Source=.;Initial Catalog=Test;Integrated Security=True " );
SqlCommand cmd = new SqlCommand( " SELECT * FROM Area " , conn);
SqlDataAdapter ada = new SqlDataAdapter(cmd);
dt = new DataTable();
ada.Fill(dt);
}
private void BindAreaForm_Load( object sender, EventArgs e)
{
BindRoot();
}
// 绑定根节点
private void BindRoot()
{
DataRow[] rows = dt.Select( " fAreaId=-1 " ); // 取根
foreach (DataRow dRow in rows)
{
TreeNode rootNode = new TreeNode();
rootNode.Tag = dRow;
rootNode.Text = dRow[ " AreaName " ].ToString();
treeView1.Nodes.Add(rootNode);
BindChildAreas(rootNode);
}
}
// 递归绑定子区域
private void BindChildAreas(TreeNode fNode)
{
DataRow dr = (DataRow)fNode.Tag; // 父节点数据关联的数据行
int fAreaId = ( int )dr[ " id " ]; // 父节点ID
DataRow[] rows = dt.Select( " fAreaId= " + fAreaId); // 子区域
if (rows.Length == 0 ) // 递归终止,区域不包含子区域时
{
return ;
}
foreach (DataRow dRow in rows)
{
TreeNode node = new TreeNode();
node.Tag = dRow;
node.Text = dRow[ " AreaName " ].ToString();
// 添加子节点
fNode.Nodes.Add(node);
// 递归
BindChildAreas(node);
}
}
}
运行截图:
代码:http://files.cnblogs.com/sndnnlfhvk/TViewSource.rar
递归示例(一):遍历二叉树 http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001015.html
递归示例(二):WinForm之TreeView的应用—绑定区域树 http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001064.html
递归示例(三):WinForm之TreeView的应用—绑定磁盘目录(一) http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001065.html
递归示例(四):WinForm之TreeView的应用—绑定磁盘目录(二) http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001072.html