|
主题: 再叙无限级分类法
|
蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#12004/11/14 1:08:29
以前写了编关于无限级分类的文章,但主要是用于Windows编程上用的,因为与treeView控件相结合。参考: blog.csdn.net/dhlhh/archive/2004/10/13/134438.aspx修正程序: blog.csdn.net/dhlhh/archive/2004/10/15/138105.aspx这次因要用到ASP.net上编程,所以以上方法有些不同了。原打算用数据结构写一个类,但觉太烦,递归编程不一定效率很高,所以从另一个角度编程,比较适合网络程序,不过也能用在WINDOWS上,只是样子不太好看。WEB中主要用于后台管理。 类的调试是在WINDOWS FORM上,如下样式 图片如下:
编辑历史:[此帖最近一次被 蓝鲸 编辑过(编辑时间:2004-11-14 20:09:08)]
非常大鱼
|
蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#22004/11/14 1:16:22
数据库分类的建立已在上文中说了,请参考以上两个链接 数据表字段:SortID、SortName、ParentID、Index(同一子族里的排位)、IsEnd
方法先建立一个Node节点的类,比较简单,我也不想详细说了
public class Node { private string mName; // 节点名 private int mID; // Id号 private int mParentID; // 父节点ID号 private int mIndex; // 每个子节点下的序号 private int mIndent; // 缩进 private string mNamePath; // 名字路径 private string mIDPath; // Id路径 private object mContent; // 内容
public string Name { get { return mName; } set { mName = value; } }
public int ID { get { return mID; } set { mID = value; } }
// .......太多了,不往下写了
public Node() { mName = ""; mID = 0; mParentID = 0; mIndex = 0; mIndent = 0; mNamePath = ""; mIDPath = ""; } }
非常大鱼
|
蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#32004/11/14 1:22:48
下面的TreeList类是关键的类,它的方法主要是用一数组存放Node,并在添加中判断插入数组的位置、缩进,并动态添加路径。路径很重要,特别是IDPath,可用于以后的搜索、插入等。
IDPath的增加方法,是在找到父节点后,路径为父类的路径+自身ID
public class TreeList { private ArrayList mNodes; // Node集合
public ArrayList Nodes { get { return mNodes; } }
public TreeList() {
}
/// <summary> /// 添加一个节点 /// </summary> public bool AddNode(Node node) { // 空节点不添加 if (node == null) { return false; }
if (mNodes.Count == 0) { // 添加根节点 if (node.ID == 0) { node.ParentID = 0; node.Name = ""; node.NamePath = "root"; node.IDPath = "0"; node.Index = 1; node.Indent = -1;
mNodes.Add((object)node);
return true; } else { return false; } } else { bool nodeFound = false; Node pNode; int iPosition = 0; // 插入点位置
for (int ndIndex = (mNodes.Count - 1); ndIndex >= 0; ndIndex--) { pNode = (Node)mNodes[ndIndex];
// 如果找到Node的ID与添加Node的父类ID号相同 if ( pNode.ID == node.ParentID ) { nodeFound = true;
node.NamePath = pNode.NamePath + "\\" + node.Name; node.IDPath = pNode.IDPath + "\\" + node.ID.ToString(); node.Indent = pNode.Indent + 1;
iPosition = ndIndex + 1;
// 查找序号比它大的节点 for ( int i = iPosition; i < mNodes.Count; i++ ) { if ( ((Node)mNodes[i]).IDPath.IndexOf(pNode.IDPath) != 0 ) { break; } else { if ( ((Node)mNodes[i]).ParentID == node.ParentID) { if ( ((Node)mNodes[i]).Index > node.Index ) { iPosition = i; break; } else { iPosition = i+1; } } else { iPosition = i + 1; } } }
// 把节点插入到数组 mNodes.Insert(iPosition, (object)node); return true; } }
if (!nodeFound) return false; }
return false; }
/// <summary> /// 重置树 /// </summary> public void ResetTreeList(ArrayList srcNodes) { mNodes = new ArrayList();
Node node = new Node(); AddNode(node);
while (srcNodes.Count > 0) { for (int i = 0; i < srcNodes.Count; i++) { if (AddNode((Node)srcNodes[i])) { srcNodes.RemoveAt(i); break; } } } } }
非常大鱼
|
蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#42004/11/14 1:30:38
用法:
先把数据从数据库导入,存放于DataSet中,并把DateSet中每行的值生成一Node对象,并添加至临时数组中。
if (dsTree.Tables["Sort"].Rows.Count > 0) { for (int i = 0; i < dsTree.Tables["Sort"].Rows.Count; i++) { nd = new Node(); nd.Name = dsTree.Tables["Sort"].Rows[i]["SortName"].ToString(); nd.ID = (int)dsTree.Tables["Sort"].Rows[i]["SortID"]; nd.ParentID = (int)dsTree.Tables["Sort"].Rows[i]["ParentID"]; nd.Index = (int)dsTree.Tables["Sort"].Rows[i]["Index"];
arrNode.Add(nd); } }
treeSort = new TreeList(); treeSort.ResetTreeList(arrNode);
这样一个树就形成了。
我这里用listBox 和comboBox来显示树的方法,当然在ASP.NET的下拉菜单中方法是差不多的,我只是调试用的。 显示函数:
private void resetView() { string strTemp;
listBox1.Items.Clear(); comboBox1.Items.Clear();
foreach (Node nd in treeSort.Nodes) { strTemp = ""; if (nd.ID != 0) { if (nd.Indent == 1) { strTemp = " ├"; } else if (nd.Indent > 1) { for (int i = 2; i <= nd.Indent + 1; i++) { strTemp += " "; } strTemp += "├"; }
strTemp += nd.Name; listBox1.Items.Add(strTemp); comboBox1.Items.Add(strTemp); } } }
点击listBox,可显示节点的路径 private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { textBox1.Text = ((Node)treeSort.Nodes[listBox1.SelectedIndex + 1]).NamePath; textBox2.Text = ((Node)treeSort.Nodes[listBox1.SelectedIndex + 1]).IDPath; }
非常大鱼
|
dreamexpress_5d
职务:普通成员
等级:1
金币:10.0
发贴:2229
|
#52004/11/17 15:25:19
好贴,学习一下!
|
蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#62004/11/17 15:56:18
声明一点,这类还没完,只是最基本的。 我自己已实现了一些图标等功能,想有空加工成可以展开子节点的,需要加属性。
方法是在Node类里加上FirstChildNode、LastChildNode、NextNode、PrevNode、Nodes集合及Expended、Visibled等属性后,即方便操作树了。
这里卖些关子了,一是代码很长,另自己成果也想留着,再加上代码还是不成熟,这里只是探讨性的。
非常大鱼
|