日期:2013-03-24  浏览次数:20428 次

在做软件是,碰上这个问题,要把一个商店的分类用树形来表示。
商品分类应该是无限子类划分的,怎样设计好一些。用数据库还是用XML。
由于以前搞设计,编程方面较生了,.NET也则开始学,觉得还是用数据库比较熟悉些。由于以前没这方面经验,所以对数据库设计感到比较辣手。
想了很多,比如链表,用一个Parent(父关系)、Child(子链接),后来舍弃了Child,就用Parent,只认父亲,于是设计数据库格式如下:
表名:Sort
字段:SortID(主键,自增长)、ParentID(父类ID号)、SortName(名称)、IsEnd(是否为最终类,因设计时考虑最终类下不能再分,最终类下只能具体商品。相反不是最终类下,只能再设类别,而不能下设具体商品)

数据库建好了,这是最简结构。现在说明一下库的使用方法。
Sort表最重要的字段就是ParentID,用于链接分类的关系。比如家族,你只要认准你父亲,而不必认爷爷,爷爷是父亲认的,即你-->父亲-->爷爷。只经认准各自的父亲(parent),这条链就链在一起了。再进一步,爷爷可以有兄弟,但这不是你考虑的,只要认得祖宗,而不必顾及傍支(即爷爷兄弟下的后代),傍支是别人考虑的事。
再说到数据库了,最顶级的类,ParentID = 0,说明没有父类;
如果一个类,它的父类是2号,则ParentID = 2;



万里长征,这才开始,要想使用它有很多问题。
比如树形搜索、删除节点,得到每个结点信息等。
以下是我用C#写的,用TreeView来表示分类树形

要定清楚,真是头大了,我不善写教程,只是提供一个思考方法。各位有好的思考方法也拿上来共享。
用树形来表示,化了我非常大精力,树形不好控制(刚用.Net不好意思),比如你点击一个子节点(node),要显示该节点的信息(包括名称或其它信息)。

要说明这个TreeView显示树形,先要知道一下TreeView添加节点方法。
TreeView字节点对象为TreeNode,可以用以下方法建立
TreeNode tn = new TreeNode("CustomerName");
在TreeView中添加节点
TreeView1.Nodes[1].Nodes[2].Add(tn);
如果想在tn节点上再加字节点
TreeNode tn2 = new TreeNode("Name2");
tn.Add(tn2);

以上只可建立固定的树,动态数的文字、及树的多少都是不确定的,如果都是tn1,tn2.....要定到什么时候去。所以考虑用数组存放这些Node的集合
ArrayList arrNode = new ArrayList();

一个简单的添加树的函数(是个思路,其实到现在还不完全)
nodeIndex:父节点在数组中的位置;
NodeName:Node的名称;
public void AddNode(int nodeIndex, string NodeName)
{
TreeNode tn = new TreeNode(NodeName);
((TreeNode)arrNode[nodeIndex]).Add(tn);
// 把新的Node添加到数组中去
arrNode.Add(tn);
}

嘿嘿,这是个不成器的函数,看似实现了,其实还没有。
因为从数据库中读出的了不会告知你应该在数组的那条下增加节点。从数据库中读出来的只有自身ID号及 ParentID。这要怎么实现,确实伤脑,因为数组中看不到任何关于ID及ParentID信息。
这个函数还要大大修改,在什么地方可以使每个Node具有ID及ParentID属性。我终于想办法编写自己的TreeNode组件了。

接下来,就得为TreeNode做些扩充。
新建组件,定义一个TreeNode的派生类:
public class ExNode : System.Windows.Forms.TreeNode

然后定义一个结构:
public struct Sort
{
public int ID;
public string Name;
public int ParentID;
public bool IsEnd;
public bool Disable;
}
该结构和数据库中相吻合。

该类的代码较简单,如下:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;


namespace CrystalBiz
{
public struct Sort
{
public int ID;
public string Name;
public int ParentID;
public bool IsEnd;
public bool Disable;
}

/// <summary>
/// ExNode 的扩展
/// </summary>
public class ExNode : System.Windows.Forms.TreeNode
{

private Sort mySort;

public Sort Sort
{
get
{
return mySort;
}
set
{
mySort = value;
this.Text = mySort.Name;
}
}

public ExNode()
{
mySort = new Sort();
}



}
}

定义好的的类,就只要把原来的TreeNode换成ExNode就行了。
这个AddNode函数现在可以改了。
/// <summary>
/// 在treeView中增加Node,并把Node加入到数组,方便查询
/// </summary>
private void AddNode(Sort st)
{
ExNode pNode = new ExNode(); //要挂接的父结点
ExNode addNode = new ExNode(); //本结点
addNode.Sort = st;

// 添加到TreeView和数组
arrNode.Add(nd);

if (nd.Sort.ParentID == 0)
{
// 最上级分类,在根节点添加
trvSort.Nodes[0].Nodes.Add(addNode);
}
else
{
// 在根目录中搜索父类,如果ParentID号与数组的ID相合,则找到
foreach (ExNode node in arrNode)