음...
TreeView를 조직도 및 여러가지 데이터를 관리하고 보여주는데 많이 사용한다.
그런데 VCL에서
TTreeView의 TTreeNode에는 담을수 있는 정보에 한계가 있다.
Text
Data
ImageIndex
StateIndex
SelectedIndex
등..
Node에 보다 많은 정보를 담아야할때(( 연결해야) 할때는 어떻게 해야하나?
방법1.
TTreeNode 클래스의 Data 프로퍼티를 활용
일반적으로 정보는 따로 가지고 있고
void *Data에다가 Poiner를 연결해서 많이 쓴다.
class TMyClass
{
public:
String sName;
};
//정보 저장
Node->Data = (void *) MyData;
//정보 활용
TMyClass *MyData=(TMyClass *)Node->Data;
MyData->sName;
방법 1-1
간단한 숫자 정보일경우
Node->Data=(void *) iNumber ; // 곧바로 숫자 정보를 집어 넣는다.
방법2
또 다른 좋은 방법으로
TTreeNode 클래스를 상속받은 Node-Class를 만들어서 Add하는 방법이 있다.
그런데 TTreeView는 TTreeNode객체를 직접생성해서 TreeView에 Add하는 방식이 아니라
TreeView를 통해서 객체를 생성한단.
바로 OnCreateNodeClass 라는 이벤트를 이용하는 것이다.
이 이벤트에서 TTreeNode를 상속받은 class의 MetaClass를 연결해주면 된다.
간단한 샘플 코드를 작성해 보았다.
프로그램 화면
샘플 코드
다음 코드는 TTreeNode를 상속받은
TGroupNode와 TPersonNode 클래스를 TTreeView의 Node객체로 Add해서 사용한 샘플인다.
//---------------------------------------------------------------------------
// Group 정보를 담는 Node-Class
//---------------------------------------------------------------------------
class TGroupNode : public TTreeNode
{
private:
String FGroupName;
String FHints;
int FTag;
public:
__property String GroupName={read=FGroupName,write=FGroupName};
__property String Hints={read=FHints,write=FHints};
__property int Tag={read=FTag,write=FTag};
};
//---------------------------------------------------------------------------
//개인(사람) 정보를 담는 Node-Class
//---------------------------------------------------------------------------
class TPersonNode : public TTreeNode
{
private:
String FName;
String FAddress;
String FPhoneNumber;
String FHints;
int FTag;
public:
__property String Name={read=FName,write=FName};
__property String Address={read=FAddress,write=FAddress};
__property String PhoneNumber={read=FPhoneNumber,write=FPhoneNumber};
__property String Hints={read=FHints,write=FHints};
__property int Tag={read=FTag,write=FTag};
};
//---------------------------------------------------------------------------
// Node의 MetaClass 정보 연결 함수
//---------------------------------------------------------------------------
void __fastcall TForm1::TreeViewCreateGroupNodeClass(TCustomTreeView *Sender, TTreeNodeClass &NodeClass)
{
NodeClass = __classid(TGroupNode);
}
void __fastcall TForm1::TreeViewCreatePersonNodeClass(TCustomTreeView *Sender, TTreeNodeClass &NodeClass)
{
NodeClass = __classid(TPersonNode);
}
//---------------------------------------------------------------------------
// TreeView에 Node 추가
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//
TGroupNode *GNode;
TPersonNode *PNode;
for(int i=0;i<3;i++)
{
//Group-Node추가
TreeView1->OnCreateNodeClass=TreeViewCreateGroupNodeClass;
GNode=(TGroupNode *)TreeView1->Items->Add(NULL,"Group"+IntToStr(i));
GNode->GroupName="그룹["+IntToStr(i)+"]";
GNode->Data=(void *)1;
//Group-Node의 Child에 Person-Node 추가
TreeView1->OnCreateNodeClass=TreeViewCreatePersonNodeClass;
for(int i=0;i<10;i++)
{
PNode=(TPersonNode *)TreeView1->Items->AddChild(GNode,"사람"+IntToStr(i));
PNode->Name="사람"+IntToStr(1);
PNode->Address="대한 민국 서울";
PNode->PhoneNumber="010-1234-5678";
PNode->Tag=i+1;
}
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// GroupNode 정보 활용
//---------------------------------------------------------------------------
void __fastcall TForm1::PmGroupNameClick(TObject *Sender)
{
if(TreeView1->Selected==NULL || TreeView1->Selected->Level!=0)return;
TGroupNode *GNode=(TGroupNode *)TreeView1->Selected;
ShowMessage(GNode->GroupName );
}
//---------------------------------------------------------------------------
// Person-Node의 정보 활용
//---------------------------------------------------------------------------
void __fastcall TForm1::PmAddressClick(TObject *Sender)
{
if(TreeView1->Selected==NULL || TreeView1->Selected->Level<1)return;
TPersonNode *PNode=(TPersonNode *)TreeView1->Selected;
ShowMessage(PNode->Address);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PmPhoneNumberClick(TObject *Sender)
{
if(TreeView1->Selected==NULL || TreeView1->Selected->Level<1)return;
TPersonNode *PNode=(TPersonNode *)TreeView1->Selected;
ShowMessage(PNode->PhoneNumber);
}
//---------------------------------------------------------------------------
원리는
원리는 간단하다.
TTreeView에는
OnCreateNodeClass 라는 이벤트가 있다.
이 이벤트 핸들러에서 원하는 Class-Type을 지정해주면
TreeView1->Items->Add() 할때 지정해준 Node-Class의 객체가 생성되는 것이다.
메신져 같은것 만들거나, 다양한 네트워크 관리 화면을 만들때 위 방식을 이용하면
참 좋을것 같다.