关于TreeView读取数据库生成树的问题

时间:2022-02-17 11:54:52

 ID     NAME   DEPPID
 1       XX     -1  -----根结点(唯一)
 2       YY     0   -----为DEPID为-1的子结点
 3       ZZ     0   -----为DEPID为-1的子结点
 4       TT     2 
 5       SS     2  ----表示为父节点ID为2
 6       QQ     2  ----表示为父节点ID为2
 7       RR     3  ----表示为父节点ID为3
..       ...   ....

怎样使树为:
        XX
          YY
             TT
             SS
             QQ
          ZZ
             RR        这种树型     表中的根结只有一个,根结点的子节的DEPPID为0,,DEPPID为0的相应子节是其DEPPID为其相应的ID。是用什么算法作比较好,FOR或递归,,给个具体的代码;

19 个解决方案

#1


将数据select出来时order by DEPPID,确保各个节点的顺序。即父节点要先被添加到TreeView中。
然后顺序的逐层添加,DEPPID可以保存到TreeItem的Data属性中,方便后续处理,或重新入库。

#2


不是TreeItem,应该是TreeNode,不好意思。

#3


帮顶

#4


select * from table order by DEPPID;
以下是實現的代碼:
    TStringList *sg_id = new TStringList;
    TStringList *sg_deppid = new TStringList;

    sg_id->Add("1=XX");
    sg_id->Add("2=YY");
    sg_id->Add("3=ZZ");
    sg_id->Add("4=TT");
    sg_id->Add("5=SS");
    sg_id->Add("6=QQ");
    sg_id->Add("7=RR");

    sg_deppid->Add("1=-1");
    sg_deppid->Add("2=0");
    sg_deppid->Add("3=0");
    sg_deppid->Add("4=2");
    sg_deppid->Add("5=2");
    sg_deppid->Add("6=2");
    sg_deppid->Add("7=3");    //整理數據 將查詢出來的内容放到兩個TStringList裏

    TTreeNode *node_parent;

    for(int i = 0; i < sg_deppid->Count; i++)
    {
        String strDeppid = sg_deppid->Values[sg_deppid->Names[i]].Trim();
        if(strDeppid == "-1")
        {
            node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim());
        }
        else if(strDeppid == "0")
        {
            TTreeNode *node = TV->Items->AddChild(node_parent,sg_id->Values[sg_id->Names[i]].Trim());
        }
        else
        {
            String strParent = sg_id->Values[strDeppid].Trim();
            for(int j = 0; j < TV->Items->Count; j++)
            {
                TTreeNode *node = TV->Items->Item[j];
                if(node->Text.Trim() == strParent)
                    TTreeNode *child_node = TV->Items->AddChild(node,sg_id->Values[sg_id->Names[i]].Trim());
            }
        }
    }

    delete sg_id;
    delete sg_deppid;

#5


/*

如果数据很多的话,而且也不知道总共有多少子层次的话

最好先只显示第1,2层的节点,(或者只显示第1层的节点)

(按你的实际情况应该是查询deppid==-1)就是第1层节点

当用户点击某层的节点时,再将这层节点的孩子节点数据从数据库读取出来,

添加到当前节点下面。这样由用户的点击来读取数据。(像Windows注册表就适合这种)

如果只是有限的数据,层数也知道,那么你可以先把所有的数据读取出来,然后根据DepID

来决定他们到底如何显示。
*/

void __fastcall TForm1::InitialTreeView(TTreeView *pTreeView,TADOConnection *pADOConnection)
{
    int uid ;
    AnsiString uname;
    TTreeNode *node,*root;
    TTreeNode *tempNode =0;
    root=node =0;
    if(!pADOConnection||!pADOConnection->Connected)
    {
     MessageBox(0,"数据库发生错误或未连接!","提示信息",MB_OK|MB_ICONWARNING);
        return ;
    }
    TADOQuery *ptrQuery =0;
    ptrQuery =new TADOQuery(this);
    ptrQuery->Connection= pADOConnection;
    AnsiString strSQL="select * from University";
    ptrQuery->SQL->Add(strSQL);
    ptrQuery->Open();
    if(ptrQuery->RecordCount>0)
    {
        uid  = ptrQuery->FieldByName("UniversityID")->AsInteger;
     uname= ptrQuery->FieldByName("UniversityName")->AsString;
        root = pTreeView->Items->AddChild(0,uname);
        root->Data=(TObject*)uid;
        root->ImageIndex =1 ;
        root->SelectedIndex =root->ImageIndex ;
    }
    else
    {
     MessageBox(0,"没有找到学校的数据","警告",MB_OK|MB_ICONWARNING);
        return ;
    }
    strSQL= "select AcademyID,AcademyName from Academy where UniversityID=:uid"; //学校下面的二级学院
    int cid;
    AnsiString cname;
    ptrQuery->Close();
    ptrQuery->SQL->Clear();
    ptrQuery->SQL->Add(strSQL);
    ptrQuery->Parameters->ParamByName("uid")->Value=uid;
    ptrQuery->Open();
    while(!ptrQuery->Eof)
    {
     cid  = ptrQuery->FieldByName("AcademyID")->AsInteger;
     cname= ptrQuery->FieldByName("AcademyName")->AsString;
        node =pTreeView->Items->AddChild(root,cname);
        node->Data =(TObject*)cid;
        node->ImageIndex = 2;
        node->SelectedIndex =node->ImageIndex ;
        tempNode = pTreeView->Items->AddChild(node,"#***#");//供显示用
         tempNode->Data = (TObject*)(-1);

        ptrQuery->Next();
    }
    ptrQuery->Close();
}


void __fastcall TForm1::TVExpanding(TObject *Sender, TTreeNode *Node,
      bool &AllowExpansion)
{

switch( Node->Level)
        {
      case 1://二级学院节点
            if(Node->Count==1&&  Node->getFirstChild() &&
               Node->getFirstChild()->Text=="#***#")
            {
             DeleteTempNode(Node);
         AddDepartment(Node);
            }
            break;
          //其他case语句略
           default: break ;
         }
}


//添加二级学院下面的系节点,就相当于你的deppid = 1的节点
void __fastcall TForm1::AddDepartment(TTreeNode *ParentNode)
{
    TTreeNode *root =0;
    int uid=-1;
    int aid= -1;
    root =ParentNode->Parent;
    if(root==0)
     return ;
    uid=(int)root->Data;
    aid=(int)ParentNode->Data ;

    AnsiString strSQL="select DepartmentID, DepartmentName from Department  ";
    strSQL +="where AcademyID=:aid  and UniversityID=:uid ";
    if(TVQuery->Active)
     TVQuery->Close();
    TVQuery->SQL->Clear();
    TVQuery->SQL->Add(strSQL);
    TVQuery->Parameters->ParamByName("aid")->Value=aid;
    TVQuery->Parameters->ParamByName("uid")->Value=uid;
    TVQuery->Open();
    int did ;
    AnsiString dname;
    TTreeNode *childNode=0;
    TTreeNode *childchildNode=0;
    while(!TVQuery->Eof)
    {
        did = TVQuery->FieldByName("DepartmentID")->AsInteger;
        dname =TVQuery->FieldByName("DepartmentName")->AsString;
        childNode =TV->Items->AddChild(ParentNode,dname);
        childNode->Data=(TObject*)did;
        childNode->ImageIndex =3;
        childNode->SelectedIndex = childNode->ImageIndex ;
        childchildNode= TV->Items->AddChild(childNode,"#***#");
        childchildNode->Data= (TObject*)(-1);
     TVQuery->Next();
    }
}

//删除临时节点
void __fastcall TForm1::DeleteTempNode(TTreeNode *tmpNode)
{
TTreeNode *childNode =tmpNode->getFirstChild();
if(childNode!=0  &&  childNode->Text=="#***#")
    {
     childNode->Delete();
    }
}
/*
 代码不方便都贴出来,只是为了说明这种层次的节点,用TreeView还是很方便的,

上面的代码就是先显示学校节点(depid=-1) 和 学校下面的二级学院节点(depid=0),

当用户点击树的第1层节点(depid=0),就是二级学院节点时,就将这个二级学院

拥有所有系的节点(depid=1)全部显示出来
*/


#6


要是很多数据时,不是要写死了啊...

#7


你那种方式是有点相象,,但我说有情况不是完全跟你一样的,数据量到底多少是不知道的啊. 我的树表示有两种类型.

#8


引用 6 楼 linzxian 的回复:
要是很多数据时,不是要写死了啊...


我只是擧例說先把數據整理好 不是說要一個一個寫
你整理數據可以用
ADOQuery去執行String strSql = "select * from table order by DEPPID"; 
然後循環結果集
    if(!ADOQuery1->Eof)
    {
        String str = ADOQuery1->FieldByName("ID")->AsString;
        str += "=" + ADOQuery1->FieldByName("Name")->AsString;
        sg_id->Add(str); 
    }
這樣不就可以了 不用去一個一個寫 都用代碼實現

#9


我觉得把
2      YY    0  -----为DEPID为-1的子结点
3      ZZ    0  -----为DEPID为-1的子结点 
改成
2      YY    1  -----表示为父节点ID为1
3      ZZ    1  -----表示为父节点ID为1 
比较合理,同一个域里数值的涵义尽量一致

#10


 到现在也没想出什么好办法啊。帮帮,谁能实现并运行成功,马上给100---分

#11


不可能把代碼完全寫出來的
實現部分的代碼就是下面的
TTreeNode *node_parent; 

    for(int i = 0; i < sg_deppid->Count; i++) 
    { 
        String strDeppid = sg_deppid->Values[sg_deppid->Names[i]].Trim(); 
        if(strDeppid == "-1") 
        { 
            node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else if(strDeppid == "0") 
        { 
            TTreeNode *node = TV->Items->AddChild(node_parent,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else 
        { 
            String strParent = sg_id->Values[strDeppid].Trim(); 
            for(int j = 0; j < TV->Items->Count; j++) 
            { 
                TTreeNode *node = TV->Items->Item[j]; 
                if(node->Text.Trim() == strParent) 
                    TTreeNode *child_node = TV->Items->AddChild(node,sg_id->Values[sg_id->Names[i]].Trim()); 
            } 
        } 
    } 

    delete sg_id; 
    delete sg_deppid;
剩下其實已經沒有什麽工作量了,就是把sg_id和sg_deppid中的數據填進去,而且也不是一條一條的寫,在select出來之後去循環結果集合然後去填數據就可以了

#12


楼上的.你这样写,你的根结点变成了子节点了啊. 这里的AddChild用得不对吧...
node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim()); 

有时间帮我写了整的,,自己测试一下,,,;;说明一下方法..

#13


你開一個新的Appication
在Form上就放一個TreeView
一個button
然後再button的click事件裏把下面的代碼複製進取,然後運行
    TStringList *sg_id = new TStringList; 
    TStringList *sg_deppid = new TStringList; 

    sg_id->Add("1=XX"); 
    sg_id->Add("2=YY"); 
    sg_id->Add("3=ZZ"); 
    sg_id->Add("4=TT"); 
    sg_id->Add("5=SS"); 
    sg_id->Add("6=QQ"); 
    sg_id->Add("7=RR"); 

    sg_deppid->Add("1=-1"); 
    sg_deppid->Add("2=0"); 
    sg_deppid->Add("3=0"); 
    sg_deppid->Add("4=2"); 
    sg_deppid->Add("5=2"); 
    sg_deppid->Add("6=2"); 
    sg_deppid->Add("7=3");    //整理數據 將查詢出來的内容放到兩個TStringList裏 

    TTreeNode *node_parent; 

    for(int i = 0; i < sg_deppid->Count; i++) 
    { 
        String strDeppid = sg_deppid->Values[sg_deppid->Names[i]].Trim(); 
        if(strDeppid == "-1") 
        { 
            node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else if(strDeppid == "0") 
        { 
            TTreeNode *node = TV->Items->AddChild(node_parent,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else 
        { 
            String strParent = sg_id->Values[strDeppid].Trim(); 
            for(int j = 0; j < TV->Items->Count; j++) 
            { 
                TTreeNode *node = TV->Items->Item[j]; 
                if(node->Text.Trim() == strParent) 
                    TTreeNode *child_node = TV->Items->AddChild(node,sg_id->Values[sg_id->Names[i]].Trim()); 
            } 
        } 
    } 

    delete sg_id; 
    delete sg_deppid;

你看看是你要的效果不

#14


對了 treeview的name改成TV 程序可以直接跑 我這裡測試沒有問題

#15


AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim());
第一個參數是父節點 我這裡用的是NULL  所以這個時候節點就是根節點

#16


sg_id->Add("1=XX"); 
    sg_id->Add("2=YY"); 
    sg_id->Add("3=ZZ"); 
    sg_id->Add("4=TT"); 
    sg_id->Add("5=SS"); 
    sg_id->Add("6=QQ"); 
    sg_id->Add("7=RR"); 

    sg_deppid->Add("1=-1"); 
    sg_deppid->Add("2=0"); 
    sg_deppid->Add("3=0"); 
    sg_deppid->Add("4=2"); 
    sg_deppid->Add("5=2"); 
    sg_deppid->Add("6=2"); 
    sg_deppid->Add("7=3");    //整理數據 將查詢出來的内容放到兩個TStringList裏   
要是数据很多的时候,要是表数据很多时,你怎么办啊.

#17


這個只是給你個例子 讓你把程序跑起來
數據多當然不可能一個一個這麽寫

直接用ADQQuery去讀數據庫 然後循環結果集 把數據填到兩個TStringList裏面 
然後循環結果集 
   ADOQuery1->Close();    //自行添加ADOConnention,并配置          
   ADOQuery1->SQL->Clear();          
   ADOQuery1->SQL->Add("select * from table order by DEPPID");          
   ADOQuery1->Open();
    if(!ADOQuery1->Eof) 
    { 
        String str = ADOQuery1->FieldByName("ID")->AsString; 
        str += "=" + ADOQuery1->FieldByName("Name")->AsString; 
        sg_id->Add(str);

        String str2 = ADOQuery1->FieldByName("ID")->AsString;
        str2 += "=" + ADOQuery1->FieldByName("sg_deppid")->AsString; 
        sg_deppid->Add(str2);
        ADOQuery1->Next();
    } 

這樣就可以把值都填到兩個TStringList裏了
不用一個一個去寫,我那麽寫只是想讓程序跑起來 讓你看看效果

#18


引用 13 楼 Ring_Pt 的回复:
你開一個新的Appication 
在Form上就放一個TreeView 
一個button 
然後再button的click事件裏把下面的代碼複製進取,然後運行 
    TStringList *sg_id = new TStringList; 
    TStringList *sg_deppid = new TStringList; 

    sg_id->Add("1=XX"); 
    sg_id->Add("2=YY"); 
    sg_id->Add("3=ZZ"); 
    sg_id->Add("4=TT"); 
    sg_id->Add("5=SS"); 
    sg_id->Add("6=QQ"); 
    sg_id->Add("7=RR"); 



node_parent =tv->Items->AddChild(NUll,sg_id->Values[sg_id->Names[i]].Trim()); 这种的过不去.类型不同吧..

#19


以前用Delphi写过,现在不记得了。

#1


将数据select出来时order by DEPPID,确保各个节点的顺序。即父节点要先被添加到TreeView中。
然后顺序的逐层添加,DEPPID可以保存到TreeItem的Data属性中,方便后续处理,或重新入库。

#2


不是TreeItem,应该是TreeNode,不好意思。

#3


帮顶

#4


select * from table order by DEPPID;
以下是實現的代碼:
    TStringList *sg_id = new TStringList;
    TStringList *sg_deppid = new TStringList;

    sg_id->Add("1=XX");
    sg_id->Add("2=YY");
    sg_id->Add("3=ZZ");
    sg_id->Add("4=TT");
    sg_id->Add("5=SS");
    sg_id->Add("6=QQ");
    sg_id->Add("7=RR");

    sg_deppid->Add("1=-1");
    sg_deppid->Add("2=0");
    sg_deppid->Add("3=0");
    sg_deppid->Add("4=2");
    sg_deppid->Add("5=2");
    sg_deppid->Add("6=2");
    sg_deppid->Add("7=3");    //整理數據 將查詢出來的内容放到兩個TStringList裏

    TTreeNode *node_parent;

    for(int i = 0; i < sg_deppid->Count; i++)
    {
        String strDeppid = sg_deppid->Values[sg_deppid->Names[i]].Trim();
        if(strDeppid == "-1")
        {
            node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim());
        }
        else if(strDeppid == "0")
        {
            TTreeNode *node = TV->Items->AddChild(node_parent,sg_id->Values[sg_id->Names[i]].Trim());
        }
        else
        {
            String strParent = sg_id->Values[strDeppid].Trim();
            for(int j = 0; j < TV->Items->Count; j++)
            {
                TTreeNode *node = TV->Items->Item[j];
                if(node->Text.Trim() == strParent)
                    TTreeNode *child_node = TV->Items->AddChild(node,sg_id->Values[sg_id->Names[i]].Trim());
            }
        }
    }

    delete sg_id;
    delete sg_deppid;

#5


/*

如果数据很多的话,而且也不知道总共有多少子层次的话

最好先只显示第1,2层的节点,(或者只显示第1层的节点)

(按你的实际情况应该是查询deppid==-1)就是第1层节点

当用户点击某层的节点时,再将这层节点的孩子节点数据从数据库读取出来,

添加到当前节点下面。这样由用户的点击来读取数据。(像Windows注册表就适合这种)

如果只是有限的数据,层数也知道,那么你可以先把所有的数据读取出来,然后根据DepID

来决定他们到底如何显示。
*/

void __fastcall TForm1::InitialTreeView(TTreeView *pTreeView,TADOConnection *pADOConnection)
{
    int uid ;
    AnsiString uname;
    TTreeNode *node,*root;
    TTreeNode *tempNode =0;
    root=node =0;
    if(!pADOConnection||!pADOConnection->Connected)
    {
     MessageBox(0,"数据库发生错误或未连接!","提示信息",MB_OK|MB_ICONWARNING);
        return ;
    }
    TADOQuery *ptrQuery =0;
    ptrQuery =new TADOQuery(this);
    ptrQuery->Connection= pADOConnection;
    AnsiString strSQL="select * from University";
    ptrQuery->SQL->Add(strSQL);
    ptrQuery->Open();
    if(ptrQuery->RecordCount>0)
    {
        uid  = ptrQuery->FieldByName("UniversityID")->AsInteger;
     uname= ptrQuery->FieldByName("UniversityName")->AsString;
        root = pTreeView->Items->AddChild(0,uname);
        root->Data=(TObject*)uid;
        root->ImageIndex =1 ;
        root->SelectedIndex =root->ImageIndex ;
    }
    else
    {
     MessageBox(0,"没有找到学校的数据","警告",MB_OK|MB_ICONWARNING);
        return ;
    }
    strSQL= "select AcademyID,AcademyName from Academy where UniversityID=:uid"; //学校下面的二级学院
    int cid;
    AnsiString cname;
    ptrQuery->Close();
    ptrQuery->SQL->Clear();
    ptrQuery->SQL->Add(strSQL);
    ptrQuery->Parameters->ParamByName("uid")->Value=uid;
    ptrQuery->Open();
    while(!ptrQuery->Eof)
    {
     cid  = ptrQuery->FieldByName("AcademyID")->AsInteger;
     cname= ptrQuery->FieldByName("AcademyName")->AsString;
        node =pTreeView->Items->AddChild(root,cname);
        node->Data =(TObject*)cid;
        node->ImageIndex = 2;
        node->SelectedIndex =node->ImageIndex ;
        tempNode = pTreeView->Items->AddChild(node,"#***#");//供显示用
         tempNode->Data = (TObject*)(-1);

        ptrQuery->Next();
    }
    ptrQuery->Close();
}


void __fastcall TForm1::TVExpanding(TObject *Sender, TTreeNode *Node,
      bool &AllowExpansion)
{

switch( Node->Level)
        {
      case 1://二级学院节点
            if(Node->Count==1&&  Node->getFirstChild() &&
               Node->getFirstChild()->Text=="#***#")
            {
             DeleteTempNode(Node);
         AddDepartment(Node);
            }
            break;
          //其他case语句略
           default: break ;
         }
}


//添加二级学院下面的系节点,就相当于你的deppid = 1的节点
void __fastcall TForm1::AddDepartment(TTreeNode *ParentNode)
{
    TTreeNode *root =0;
    int uid=-1;
    int aid= -1;
    root =ParentNode->Parent;
    if(root==0)
     return ;
    uid=(int)root->Data;
    aid=(int)ParentNode->Data ;

    AnsiString strSQL="select DepartmentID, DepartmentName from Department  ";
    strSQL +="where AcademyID=:aid  and UniversityID=:uid ";
    if(TVQuery->Active)
     TVQuery->Close();
    TVQuery->SQL->Clear();
    TVQuery->SQL->Add(strSQL);
    TVQuery->Parameters->ParamByName("aid")->Value=aid;
    TVQuery->Parameters->ParamByName("uid")->Value=uid;
    TVQuery->Open();
    int did ;
    AnsiString dname;
    TTreeNode *childNode=0;
    TTreeNode *childchildNode=0;
    while(!TVQuery->Eof)
    {
        did = TVQuery->FieldByName("DepartmentID")->AsInteger;
        dname =TVQuery->FieldByName("DepartmentName")->AsString;
        childNode =TV->Items->AddChild(ParentNode,dname);
        childNode->Data=(TObject*)did;
        childNode->ImageIndex =3;
        childNode->SelectedIndex = childNode->ImageIndex ;
        childchildNode= TV->Items->AddChild(childNode,"#***#");
        childchildNode->Data= (TObject*)(-1);
     TVQuery->Next();
    }
}

//删除临时节点
void __fastcall TForm1::DeleteTempNode(TTreeNode *tmpNode)
{
TTreeNode *childNode =tmpNode->getFirstChild();
if(childNode!=0  &&  childNode->Text=="#***#")
    {
     childNode->Delete();
    }
}
/*
 代码不方便都贴出来,只是为了说明这种层次的节点,用TreeView还是很方便的,

上面的代码就是先显示学校节点(depid=-1) 和 学校下面的二级学院节点(depid=0),

当用户点击树的第1层节点(depid=0),就是二级学院节点时,就将这个二级学院

拥有所有系的节点(depid=1)全部显示出来
*/


#6


要是很多数据时,不是要写死了啊...

#7


你那种方式是有点相象,,但我说有情况不是完全跟你一样的,数据量到底多少是不知道的啊. 我的树表示有两种类型.

#8


引用 6 楼 linzxian 的回复:
要是很多数据时,不是要写死了啊...


我只是擧例說先把數據整理好 不是說要一個一個寫
你整理數據可以用
ADOQuery去執行String strSql = "select * from table order by DEPPID"; 
然後循環結果集
    if(!ADOQuery1->Eof)
    {
        String str = ADOQuery1->FieldByName("ID")->AsString;
        str += "=" + ADOQuery1->FieldByName("Name")->AsString;
        sg_id->Add(str); 
    }
這樣不就可以了 不用去一個一個寫 都用代碼實現

#9


我觉得把
2      YY    0  -----为DEPID为-1的子结点
3      ZZ    0  -----为DEPID为-1的子结点 
改成
2      YY    1  -----表示为父节点ID为1
3      ZZ    1  -----表示为父节点ID为1 
比较合理,同一个域里数值的涵义尽量一致

#10


 到现在也没想出什么好办法啊。帮帮,谁能实现并运行成功,马上给100---分

#11


不可能把代碼完全寫出來的
實現部分的代碼就是下面的
TTreeNode *node_parent; 

    for(int i = 0; i < sg_deppid->Count; i++) 
    { 
        String strDeppid = sg_deppid->Values[sg_deppid->Names[i]].Trim(); 
        if(strDeppid == "-1") 
        { 
            node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else if(strDeppid == "0") 
        { 
            TTreeNode *node = TV->Items->AddChild(node_parent,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else 
        { 
            String strParent = sg_id->Values[strDeppid].Trim(); 
            for(int j = 0; j < TV->Items->Count; j++) 
            { 
                TTreeNode *node = TV->Items->Item[j]; 
                if(node->Text.Trim() == strParent) 
                    TTreeNode *child_node = TV->Items->AddChild(node,sg_id->Values[sg_id->Names[i]].Trim()); 
            } 
        } 
    } 

    delete sg_id; 
    delete sg_deppid;
剩下其實已經沒有什麽工作量了,就是把sg_id和sg_deppid中的數據填進去,而且也不是一條一條的寫,在select出來之後去循環結果集合然後去填數據就可以了

#12


楼上的.你这样写,你的根结点变成了子节点了啊. 这里的AddChild用得不对吧...
node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim()); 

有时间帮我写了整的,,自己测试一下,,,;;说明一下方法..

#13


你開一個新的Appication
在Form上就放一個TreeView
一個button
然後再button的click事件裏把下面的代碼複製進取,然後運行
    TStringList *sg_id = new TStringList; 
    TStringList *sg_deppid = new TStringList; 

    sg_id->Add("1=XX"); 
    sg_id->Add("2=YY"); 
    sg_id->Add("3=ZZ"); 
    sg_id->Add("4=TT"); 
    sg_id->Add("5=SS"); 
    sg_id->Add("6=QQ"); 
    sg_id->Add("7=RR"); 

    sg_deppid->Add("1=-1"); 
    sg_deppid->Add("2=0"); 
    sg_deppid->Add("3=0"); 
    sg_deppid->Add("4=2"); 
    sg_deppid->Add("5=2"); 
    sg_deppid->Add("6=2"); 
    sg_deppid->Add("7=3");    //整理數據 將查詢出來的内容放到兩個TStringList裏 

    TTreeNode *node_parent; 

    for(int i = 0; i < sg_deppid->Count; i++) 
    { 
        String strDeppid = sg_deppid->Values[sg_deppid->Names[i]].Trim(); 
        if(strDeppid == "-1") 
        { 
            node_parent = TV->Items->AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else if(strDeppid == "0") 
        { 
            TTreeNode *node = TV->Items->AddChild(node_parent,sg_id->Values[sg_id->Names[i]].Trim()); 
        } 
        else 
        { 
            String strParent = sg_id->Values[strDeppid].Trim(); 
            for(int j = 0; j < TV->Items->Count; j++) 
            { 
                TTreeNode *node = TV->Items->Item[j]; 
                if(node->Text.Trim() == strParent) 
                    TTreeNode *child_node = TV->Items->AddChild(node,sg_id->Values[sg_id->Names[i]].Trim()); 
            } 
        } 
    } 

    delete sg_id; 
    delete sg_deppid;

你看看是你要的效果不

#14


對了 treeview的name改成TV 程序可以直接跑 我這裡測試沒有問題

#15


AddChild(NULL,sg_id->Values[sg_id->Names[i]].Trim());
第一個參數是父節點 我這裡用的是NULL  所以這個時候節點就是根節點

#16


sg_id->Add("1=XX"); 
    sg_id->Add("2=YY"); 
    sg_id->Add("3=ZZ"); 
    sg_id->Add("4=TT"); 
    sg_id->Add("5=SS"); 
    sg_id->Add("6=QQ"); 
    sg_id->Add("7=RR"); 

    sg_deppid->Add("1=-1"); 
    sg_deppid->Add("2=0"); 
    sg_deppid->Add("3=0"); 
    sg_deppid->Add("4=2"); 
    sg_deppid->Add("5=2"); 
    sg_deppid->Add("6=2"); 
    sg_deppid->Add("7=3");    //整理數據 將查詢出來的内容放到兩個TStringList裏   
要是数据很多的时候,要是表数据很多时,你怎么办啊.

#17


這個只是給你個例子 讓你把程序跑起來
數據多當然不可能一個一個這麽寫

直接用ADQQuery去讀數據庫 然後循環結果集 把數據填到兩個TStringList裏面 
然後循環結果集 
   ADOQuery1->Close();    //自行添加ADOConnention,并配置          
   ADOQuery1->SQL->Clear();          
   ADOQuery1->SQL->Add("select * from table order by DEPPID");          
   ADOQuery1->Open();
    if(!ADOQuery1->Eof) 
    { 
        String str = ADOQuery1->FieldByName("ID")->AsString; 
        str += "=" + ADOQuery1->FieldByName("Name")->AsString; 
        sg_id->Add(str);

        String str2 = ADOQuery1->FieldByName("ID")->AsString;
        str2 += "=" + ADOQuery1->FieldByName("sg_deppid")->AsString; 
        sg_deppid->Add(str2);
        ADOQuery1->Next();
    } 

這樣就可以把值都填到兩個TStringList裏了
不用一個一個去寫,我那麽寫只是想讓程序跑起來 讓你看看效果

#18


引用 13 楼 Ring_Pt 的回复:
你開一個新的Appication 
在Form上就放一個TreeView 
一個button 
然後再button的click事件裏把下面的代碼複製進取,然後運行 
    TStringList *sg_id = new TStringList; 
    TStringList *sg_deppid = new TStringList; 

    sg_id->Add("1=XX"); 
    sg_id->Add("2=YY"); 
    sg_id->Add("3=ZZ"); 
    sg_id->Add("4=TT"); 
    sg_id->Add("5=SS"); 
    sg_id->Add("6=QQ"); 
    sg_id->Add("7=RR"); 



node_parent =tv->Items->AddChild(NUll,sg_id->Values[sg_id->Names[i]].Trim()); 这种的过不去.类型不同吧..

#19


以前用Delphi写过,现在不记得了。

#20