读书人

TreeView设立节点不同高度一种实现

发布时间: 2013-10-27 15:21:49 作者: rapoo

TreeView设置节点不同高度一种实现
效果如下
TreeView设立节点不同高度一种实现
为了实现不同节点有不同的高度,本想重新做个TreeView,但是时间来不急了,只好想了个折中的办法


const int nGroupItemHeight = 22;
const int nNormalItemHeight = 30;
const int nSelectedItemHeight = 50;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
tvInfo->DoubleBuffered = true;

int cyItemHeight = 1;
SendMessage(tvInfo->Handle,TVM_SETITEMHEIGHT,(WPARAM)(SHORT)cyItemHeight,0);//修改节点高度至1像素

}
//---------------------------------------------------------------------------
void __fastcall TForm1::tvInfoCustomDrawItem(TCustomTreeView *Sender, TTreeNode *Node,
TCustomDrawState State, bool &DefaultDraw)
{
//以下参考妖哥的ListBox自绘
DefaultDraw = false;

TRect Rect = Node->DisplayRect(false);
// 填充的背景颜色
Sender->Canvas->Brush->Color = clWhite;
// 文字颜色
Sender->Canvas->Font->Color = clBlack;
// 填充背景
Sender->Canvas->FillRect (Rect) ;
// 圆角矩形的背景颜色
Sender->Canvas->Brush->Color = TColor(0x00FFF7F7);
// 圆角矩形的边框颜色
Sender->Canvas->Pen->Color = TColor(0x00131315);
// 画出圆角矩形
Sender->Canvas->RoundRect(Rect.Left + 3, Rect.Top + 3,
Rect.Right - 2, Rect.Bottom - 2, 8, 8);
// 以不同的宽度和高度再画一次,实现立体效果
Sender->Canvas->RoundRect(Rect.Left + 3, Rect.Top + 3,
Rect.Right - 3, Rect.Bottom - 3, 5, 5);


// 如果是当前选中项
if(State.Contains(odSelected))
{

// 选中项的背景颜色
Sender->Canvas->Brush->Color = TColor(0x00FFB2B5);
// 以不同的背景色画出选中项的圆角矩形
Sender->Canvas->RoundRect(Rect.Left + 3, Rect.Top + 3,
Rect.Right - 3, Rect.Bottom - 3, 5, 5);
// 选中项的文字颜色
Sender->Canvas->Font->Color = clBlue;

// 如果当前项拥有焦点
if(State.Contains(odFocused))
// 重画焦点虚框,实际上就是擦除了原先的焦点虚框
// 我看到CnPack的设置中好象没有去除那个框. ccrun注
::DrawFocusRect(Sender->Canvas->Handle, &Rect);



}
// 画出图标
ImageList1->Draw(Sender->Canvas, Rect.Left + 7 + (nTimer%2),
Rect.top + (Rect.Height() - ImageList1->Height)/2, 1, true);
// Item的第一行文字
Sender->Canvas->TextOutA(Rect.Left + Node->Level*32 + 20, Rect.Top + 4,
Node->Text);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnInitClick(TObject *Sender)
{
tvInfo->Items->Clear();
tvInfo->Items->BeginUpdate();
for(int nGroupIndex=0;nGroupIndex<100;nGroupIndex++)
{
TTreeNode* nGroupNode = tvInfo->Items->Add(NULL,"Group"+IntToStr(nGroupIndex));
TVITEMEX itemEx;
TTreeNode* nCurrNode = nGroupNode;
itemEx.hItem = nCurrNode->ItemId;
itemEx.mask = TVIF_INTEGRAL;
itemEx.iIntegral = nGroupItemHeight;
SendMessage(tvInfo->Handle,TVM_SETITEM, 0, LPARAM(&itemEx));//调整高度
for(int nItem=0;nItem<10;nItem++)
{
TTreeNode* nNode = tvInfo->Items->AddChild(nGroupNode,"Item"+IntToStr(nItem));

TVITEMEX itemEx;
TTreeNode* nCurrNode = nNode;
itemEx.hItem = nCurrNode->ItemId;


itemEx.mask = TVIF_INTEGRAL;
itemEx.iIntegral = nNormalItemHeight;
SendMessage(tvInfo->Handle,TVM_SETITEM, 0, LPARAM(&itemEx));//调整高度

}
}

tvInfo->Items->EndUpdate();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::tvInfoChanging(TObject *Sender, TTreeNode *Node, bool &AllowChange)

{
//

tvInfo->Items->BeginUpdate();
TTreeNode* nCurrNode = NULL;
TVITEMEX itemEx;

if( tvInfo->Selected != NULL )
{

nCurrNode = tvInfo->Selected;
if( nCurrNode->Level != 0 )
{
itemEx.hItem = nCurrNode->ItemId;
itemEx.mask = TVIF_INTEGRAL;
itemEx.iIntegral = nNormalItemHeight;
SendMessage(tvInfo->Handle,TVM_SETITEM, 0, LPARAM(&itemEx));//还原选中节点高度
}
}


nCurrNode = Node;
if( nCurrNode->Level != 0 )
{
itemEx.hItem = nCurrNode->ItemId;
itemEx.mask = TVIF_INTEGRAL;
itemEx.iIntegral = nSelectedItemHeight;
SendMessage(tvInfo->Handle,TVM_SETITEM, 0, LPARAM(&itemEx));//更改新的选中节点高度
}

tvInfo->Items->EndUpdate();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::tvInfoMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
int X, int Y)
{
//自绘模式下行选
TTreeNode *ClickNode;
ClickNode = tvInfo->GetNodeAt(X, Y);
if(ClickNode != NULL)
ClickNode->Selected = true;
}
//---------------------------------------------------------------------------



存在问题:
当节点数量过多时,控件选中反应有点迟钝,估计是由于BeginUpdate和EndUpdate造成的,但是如果去掉这个好像在自绘函数里面DisplayRect计算的矩形区域就会有错,不知是否有好的办法可以修改一下
[解决办法]
好,帮你顶一下
以前看过,有比较完善的三方控件,你可以直接用一下
[解决办法]
devexpress可以做出很多效果。
[解决办法]
引用:
效果如下

为了实现不同节点有不同的高度,本想重新做个TreeView,但是时间来不急了,只好想了个折中的办法



C/C++ code
?



123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616……

研究一下

读书人网 >C++ Builder

热点推荐