2014-12-03 130 views
8

我試圖創建TVirtualStringTree視圖,這將是類似這樣的:VirtualTreeView - 在同一節點不同顏色的文字

Folder view with different font colors

在上面的例子中,我已經表明了一些我想要達到的可能場景。 文件夾A具有粗體文本,然後在同一節點後面顯示紅色的無襯線文本。我正在尋找做出這種輸出的方式。

但是,如果這是太硬或太有問題的創建,我將很高興與FolderB中FolderC類型的輸出 - 這也許可以有2列,包含一個文件夾名稱,另一種含發裏面的文件數。

FolderD在這裏只是作爲沒有文件和該文件夾的輸出(文本是unbolded,沒有數字)的文件夾的示例。

我正在尋找任何方向如何使這種效果,因爲似乎VirtualTreeView只能有一個顏色或粗體設置每個節點。任何提示或建議如何向FolderA方向移動FolderBFolderC高度讚賞,所以我有一個起點。 Delphi或C++ Builder示例都是受歡迎的(最終代碼將在C++ Builder中)。

+1

您可以處理'OnMeasureTextWidth'事件提供整體文本的寬度並在'OnDrawText'事件處理程序中呈現兩個文本。但我會親自使用2列,這將允許用戶總是看到計數。 – TLama 2014-12-03 16:09:06

+0

@TLama我同意2列確實有它的優勢,我很可能會在以後再切換到這一列。但是在這個時候我需要一個快速的解決方案,'toShowStaticText'就是這麼做的。不幸的是,我只能接受一個答案,因爲你的答案都是很好的解決方案。 – Coder12345 2014-12-03 16:30:45

+1

我['不會看到任何]](http://pastebin.com/4G9TzSHL)更復雜地處理'OnPaintText'並在兩欄的情況下切換'Column'。 – TLama 2014-12-03 16:49:17

回答

12

你可以簡單地使用toShowStaticTextStringOptions)選項:

implementation 

type 
    PNodeRec = ^TNodeRec; 
    TNodeRec = record 
    Name: WideString; 
    Count: Integer; 
    IsBold: Boolean; 
    end; 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    Node: PVirtualNode; 
    NodeRec: PNodeRec; 
    I: Integer; 
begin 
    VirtualStringTree1.TreeOptions.StringOptions := 
    VirtualStringTree1.TreeOptions.StringOptions + [toShowStaticText]; 
    VirtualStringTree1.NodeDataSize := Sizeof(TNodeRec); 
    // Populate some data 
    for I := 1 to 10 do 
    begin 
    Node := VirtualStringTree1.AddChild(nil); 
    NodeRec := VirtualStringTree1.GetNodeData(Node); 
    Initialize(NodeRec^); 
    NodeRec.Name := 'Node' + IntToStr(I); 
    NodeRec.Count := I; 
    NodeRec.IsBold := I mod 2 = 0; 
    end; 
end; 

procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; 
    var CellText: WideString); 
var 
    NodeRec: PNodeRec; 
begin 
    NodeRec := PNodeRec(TVirtualStringTree(Sender).GetNodeData(Node)); 
    if TextType = ttNormal then 
    CellText := NodeRec^.Name 
    else // ttStatic 
    CellText := Format('(%d)', [NodeRec^.Count]); 
end; 

procedure TForm1.VirtualStringTree1PaintText(Sender: TBaseVirtualTree; 
    const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; 
    TextType: TVSTTextType); 
var 
    NodeRec: PNodeRec; 
begin 
    NodeRec := PNodeRec(TVirtualStringTree(Sender).GetNodeData(Node)); 
    if TextType = ttNormal then 
    begin 
    if NodeRec^.IsBold then 
     TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsBold]; 
    end 
    else // ttStatic 
    TargetCanvas.Font.Color := clRed; 
end; 

輸出:

enter image description here

+0

那太容易了!我試了一下,效果很好,謝謝!我現在唯一的小問題是靜態部分在右側太多了(就像一個額外的空間左右)。這個'ttStatic'的左邊距(或者'ttNormal'的右邊距)是否也可以調整? – Coder12345 2014-12-03 16:29:07

+1

我不知道這樣的內置功能(但我也使用一個相當舊的VT版本)。你可以在PaintText事件上處理圖形(而不是爲'ttStatic'處理'GetText')。你有'Canvas' +'TargetCanvas'。根據需要定位文本。 – kobik 2014-12-03 16:45:58

+3

+你有'TextMargin'屬性。這將影響正常和靜態文本。 – kobik 2014-12-03 16:48:16