通过数据表动态建Treeview,绝对高效率!

/*

1。数据库表的结构:
   (
       节点ID
       节点父ID(PID)
       及其他字段
    )
   ID,PID的类型无所谓,数字,字符都行,也不需要有规律,
  只要保证ID字段为主键即可,比如可以用GUID 来作ID。
  支持无限级。

2。TTreeNode的Data指向一个结构,结构内有一个域记录节点的ID及PID,
      其他的域根据需要可自己定义。

3。从数据库生成树,这是要好好考虑的,要作到效率高,最重要的是“避免反复查询
     数据库或遍历数据集”,最好是查询一次就能生成整棵树。
    
     主要思想是:先生成一棵全是根节点的树,再做调整,这样就避免了先读出子节点,
     找不到父节点的尴尬。
*/

struct NODEDATA  //节点关联的数据
{
  int         id;
  int         pid;
  AnsiString  name;
  AnsiString  memo; //其他域省略...
};

void __fastcall FillTree()
{
  struct NODEDATA *ndata=NULL;
  TStringList     *ss=NULL;

  TTreeNode   *aNode=NULL;
  TTreeNode   *bNode=NULL;
  TTreeNode   *pNode=NULL;

  Query1->Close();
  Query1->SQL->Text="select id,pid,name,memo from tree_tab";
  Query1->SQL->Open();

  try
  {
    ss=new TStringList();
    TreeView->Items->BeginUpdate();//禁止刷新,提高速度
    //遍历记录集
    for(Query1->First(); !Query1->Eof; Query1->Next())
    {
      ndata=new NodeData();
      ndata->id   = Query1->FieldByName("id")->AsInteger;
      ndata->pid  = Query1->FieldByName("id")->AsInteger;
      ndata->name = Query1->FieldByName("name")->AsString;
      ndata->memo = Query1->FieldByName("memo")->AsString;
      //生成一个根节点加入TreeView
      aNode=TreeView1->Items->AddObject(NULL,ndata->name,ndata);
      //记录id-TreeNode对应关系,便于下面查找
      ss->AddObject(AnsiString(ndata->id),aNode);
    }
    Query1->Close();
    ndata=NULL;
    
   //下面是关键!!
 
   //调整树,根据节点的pid,把节点移到相应的TreeNode下
    int idx;
    for(aNode=TreeView1->Items->GetFirstNode(); aNode!=NULL ;)
    {
      ndata = (NODEDATA*)(aNode->Data);
      if(-1==(idx=ss->IndexOf(AnsiString(ndata->pid))))
      {
        aNode=aNode->getNextSibling();
        continue;
      }
      else
      {
        pNode = (TTreeNode*)(ss->Objects[idx]);
        bNode=aNode;
        aNode=aNode->getNextSibling();
        bNode->MoveTo(pNode,naAddChild);
      } 
    }
  }
  __finally
  {
    delete ss; ss=NULL;
    Query1->Close();
    TreeView->Items->EndUpdate();
  }
}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=129886


<script src="http://localhost:82/PromoteIcon.aspx?id=129886" type="text/javascript"></script> [ 收藏到我的网摘]   myy发表于 2004年10月09日 20:48:00
href="http://blog.csdn.net/myy/Services/Pingback.aspx" rel="pingback" /> <script type="text/javascript">function hide(){showComment();}</script>


 

#   ghslinux 发表于2004-11-06 18:09:00  IP: 221.224.207.*
ndata=new NodeData();
输入错误,小错,呵呵


万分感谢!

#   ghslinux 发表于2004-11-06 18:10:00  IP: 221.224.207.*
应该是
ndata=new DODEDATA();

#   CoonyPie 发表于2004-12-06 23:17:00  IP: 220.163.61.*
好,非常感谢!

刚刚开始学习BCB,希望能和你交个朋友。

QQ:340072197

#   流星 发表于2004-12-06 23:37:00  IP: 220.190.138.*
能否提供一个delphi版的,非常感谢……

#   northwindrocker 发表于2005-10-24 14:42:00  IP: 211.100.21.*
楼主我按你的办法在DELPHI中实现了一下,到了调整的时候不行了,TREEVIEW中什么也没有了.

#   xuhuai 发表于2006-05-10 18:15:00  IP: 222.45.198.*
我所关心的是,id,pid 假如没有规律,如何能在数据表中查询一个节点,包括所有子节点的记录。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值