大家来帮我想想办法,这个的实现思路

lffxgthmhfy 2009-04-01 09:48:09
我想做一个显示分类的树。在表中有一张分类信息表。它也对应有实体类:

public class TypeInfo
{
int type_id;

public int _Type_id
{
get { return type_id; }
set { type_id = value; }
}

string typeName;

public string _TypeName
{
get { return typeName; }
set { typeName = value; }
}

string typeLayer;

public string _TypeLayer
{
get { return typeLayer; }
set { typeLayer = value; }
}
}

为了表示分类信息之间的关系。我在表中有一个字符串字段 TypeLayer

表示形式:(“-”只是起分隔作用)
如一级目录,用一个INT代表,1,3,2等;(值大小只代表它们次序)
从二级开始就要考虑它的父节点了,所以我表示为1-1(一级目录1 下的第1个节点) 。3-1(一级目录下3 的第1个节点),2-4(一级目录下的第2个节点下的第4个节点);
如四级目录就表示为这样的形式:2-3-2-6(一级目录下2 下的第3个节点下的第2个节点下的第6个节点)

现在想做一个方法,输入一个LIST〈TypeInfo〉(TypeInfo就是上面的类),输出一个对应的System.Web.UI.WebControls.TreeView 各位大哥大姐们帮我看看,怎么实现方便。谢谢大家。

...全文
194 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ztenv 2009-04-01
  • 打赏
  • 举报
回复
层号是多余的(当你父结点移动时,你需要改的还有层号这个属性,可以说是冗余的),有了父结点ID后,一切都能搞定,
lffxgthmhfy 2009-04-01
  • 打赏
  • 举报
回复
我现在将 TypeLayer 字段的表示改了,
形式为:层号(就是第几级) - 父节点ID(对应type_id主键)



如 3-4 表示第三级,父节点是type_id的记录。这样表示看起来简单多了,刚才的表现是有问题的,它生成的树与表基本没关系,反向修改就实现不了,而且查找父节点也很复杂。现在这个查找父节点依次加入树还是很麻烦。递规可能很有用,可不是很熟。
lffxgthmhfy 2009-04-01
  • 打赏
  • 举报
回复
我现在将 TypeLayer 字段的表示改了,
形式为:层号(就是第几级) - 父节点ID(对应type_id主键)



如 3-4 表示第三级,父节点是type_id的记录。这样表示看起来简单多了,刚才的表现是有问题的,它生成的树与表基本没关系,反向修改就实现不了,而且查找父节点也很复杂。现在这个查找父节点依次加入树还是很麻烦。递规可能很有用,可不是很熟。
cancerser 2009-04-01
  • 打赏
  • 举报
回复
方式不太好.
如楼上很多位所说
如果是个平行的数组,只需要表明父子关系就好了.你只需要一个关系
而树形结构最好的对应关系,在你这里还是存对象最好
我给你个例子吧

public class TypeInfo
{
int type_id;

public int _Type_id
{
get { return type_id; }
set { type_id = value; }
}

string typeName;

public string _TypeName
{
get { return typeName; }
set { typeName = value; }
}

string typeLayer;

public TypeInfo 父TypeInfo {
get ;
set ;
}
public TypeInfo 子TypeInfo
{
get ;
set ;
}
}

//这样存出来的 是树的列表
fanbo 2009-04-01
  • 打赏
  • 举报
回复
不明白,帮你顶吧!学习了。
ztenv 2009-04-01
  • 打赏
  • 举报
回复
这样做貌似有点不太合理:
1、可以考虑一下“对象结构型模式”,每个结点加一个Parentid来标识此结点的父结点;每个结点对象无需知道它的爷爷结点(由其父结点可取得),这样会使程序变得简单些;
2、最好是分级查找数据库中的数据,先组织根,再遍历的去组织数据,直接数据完成,此时在内存中就存在了一个逻辑上的树,通过一个根结点,可以取得任何一个结点;
linaren 2009-04-01
  • 打赏
  • 举报
回复
以前实现过类似功能:
1。表结构中节点编码固定位数,比如节点两位既是00-99范围内
2。树的不必递轨实现,选出数据按编码排序即可。

有上面的规则的实现参考如下代码:
/// <summary>
/// 初始化部门树状结构。
/// </summary>
/// <remarks>
/// 考虑到性能因素,在部门树的Tag属性中保存了一个Hashtable对象,
/// 用来保存此树上所有节点信息。所以在维护在对树添加、修改、删除,移动节点时
/// 都必须考虑对此属性的修改。
/// </remarks>
/// <param name="tv">部门树对象</param>
/// <param name="dt">部门数据集合</param>
public void InitTreeView(TreeView tv ,DataTable dt)
{
if( dt == null || dt.Rows.Count == 0 || tv == null ) return ;

TreeNode tn = null ;
string bmid = null ;
string bmmc = null ;
string ztbh = null ; //帐套编号
Hashtable ht = null ;

//清空所有节点
tv.Nodes.Clear( ) ;

ht = new Hashtable( ) ;
//按表的记录的顺序添加树节点
foreach (DataRow dr in dt.Rows ) {

bmid = ((string)dr["BMID"]).Trim();
bmmc = ((string)dr["BMMC"]).Trim();
ztbh = dr["ZTBH"].ToString().Trim() ;

//logger.Info("bmid:" + bmid);

tn = new TreeNode(bmmc);
tn.Tag = bmid ;


//如果该节点是对应具体的帐套则标识为红色
tn.ForeColor = (ztbh.Trim().Length>0)?Color.Blue:Color.Black ;
//tn.ExpandAll() ;
//
ht.Add(bmid ,tn) ;

if( tv.SelectedNode == null ) {//是根节点时bmid.Length == this.BaseLength
tv.Nodes.Add( tn ) ;
tv.SelectedNode = tn ;
} else {//非根节点时

if(tv.SelectedNode.Tag.ToString().Length > bmid.Length){//当前遍历节点是该节点的子节点
tv.SelectedNode = tv.SelectedNode.Parent ;
//考虑到会出现断层的现象(例如在具体的帐套里添加的部门不在系统里出现就出现了断层)
TreeNode temp = tv.SelectedNode.Parent ;//curSelParent
//一直找到于当前节点同级别的节点
while (tv.SelectedNode != null && tv.SelectedNode.Tag.ToString().Length != bmid.Length ){
//curSelParent = tv.SelectedNode ;
tv.SelectedNode = tv.SelectedNode.Parent ;
}
if(tv.SelectedNode == null )
{
tv.SelectedNode = temp ;
temp.Nodes.Add( tn ) ;
continue ;
}
//在同级别的节点上添加该节点
if(tv.SelectedNode.Tag.ToString().Length == this.BaseLength){
tv.Nodes.Add(tn);
tv.SelectedNode = tn ;
} else {
tv.SelectedNode = tv.SelectedNode.Parent ;
tv.SelectedNode.Nodes.Add(tn);
tv.SelectedNode = tn ;
}
} else if(tv.SelectedNode.Tag.ToString().Length < bmid.Length){//当前遍历节点是该节点上级节点时
tv.SelectedNode.Nodes.Add(tn);
tv.SelectedNode = tn ;
} else if(tv.SelectedNode.Tag.ToString().Length == bmid.Length) {//当前遍历节点与该节点同级
if(tv.SelectedNode.Tag.ToString().Length == this.BaseLength){
tv.Nodes.Add(tn);
tv.SelectedNode = tn ;
} else {
tv.SelectedNode = tv.SelectedNode.Parent ;
tv.SelectedNode.Nodes.Add(tn) ;
tv.SelectedNode = tn ;
}
} //end if
}//end if
}//enf foreach

// set the first root as selected node
if( tv.Nodes.Count > 0 )
{
tv.SelectedNode = tv.Nodes[0] ;
tv.SelectedNode.Expand() ;
tv.Tag = ht ;
}

// //折叠所有节点
// tv.CollapseAll();
}//end method
gciyfzx07 2009-04-01
  • 打赏
  • 举报
回复
可以将TypeLayer分隔成数组,判断数组长度,分别添加。
十八道胡同 2009-04-01
  • 打赏
  • 举报
回复
你存的格式很好,所以就可以很简单的找出父节点子节点.方法就是1,2楼的方法.
fenglm999 2009-04-01
  • 打赏
  • 举报
回复
我认为你可以再加一个字段叫typarent,来判断是不是父节点,比如说id为5的父借点为1 那么typarent对应的就为1,在数据库这边传入一个id,就可以找到对应的子节点
chuxue1342 2009-04-01
  • 打赏
  • 举报
回复
这样比较好点:
你先判断indexof("-")是否有返回值,没有的话,在根节点添加,有的话,再找父节点!
chuxue1342 2009-04-01
  • 打赏
  • 举报
回复
动态添加树节点不难!主要是你要找出他的爷节点,然后添加树节点就可以了!按照你的描述,你可以截取TypeLayer字符串,如:
TypeLayer.SubString(0,TypeLayer.LastIndexof("-"))得到父节点,遍历树添加进去就可以了!

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧