2018-03-20

VirtualStringTree Column CheckBox

如何在 VirtualStringTree 上顯示 CheckBox

前面實作了 [ VirtualStringTree Load DataSet - Event ] 與 [ VirtualStringTree Filter Node ] 可以感覺得出來,VirtualStringTree 並不是最快的 Tree。所以還有另一個需求、多 Column。

A. Column 上的 CheckBox

如何在其他 Column 放上 CheckBox。呼叫 WinApi 的 DrawFrameControl 就可以輕鬆完成,比我想像中的簡單。

A1.畫上CheckBox

在 OnAfterCellPaint 開始畫。這裡可以看到 Winapi.Windows 內的樣式,不只有 CheckBox 連 RadioButton 也可以。
uses Winapi.Windows;

procedure TfrmFilterCust.vstAfterCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellRect: TRect);
var
  vANode: PCustNode;
begin
  if Column = 3 then
  begin
    vANode := Sender.GetNodeData(Node);
    if vANode.IsCustomer then
      DrawFrameControl(TargetCanvas.Handle, CellRect, DFC_BUTTON, DFCS_CHECKED)
    else
      DrawFrameControl(TargetCanvas.Handle, CellRect, DFC_BUTTON, DFCS_BUTTONCHECK);
  end
  else if Column = 4 then
  begin
    vANode := Sender.GetNodeData(Node);
    if vANode.IsSupplier then
      DrawFrameControl(TargetCanvas.Handle, CellRect, DFC_BUTTON, DFCS_CHECKED)
    else
      DrawFrameControl(TargetCanvas.Handle, CellRect, DFC_BUTTON, DFCS_BUTTONCHECK);
  end;
end;

A2.點擊CheckBox

先取得滑鼠 OnMouseDown 點選的 Node。
procedure TfrmFilterCust.vstMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FSeledNode := vst.GetNodeAt(X, Y);
end;

在 OnColumnClick 事件中修改資料屬性,在呼叫重畫 RepaintNode。
procedure TfrmFilterCust.vstColumnClick(Sender: TBaseVirtualTree;
  Column: TColumnIndex; Shift: TShiftState);
var
  vANode: PCustNode;
begin
  if Column = 3 then
  begin
    vANode := Sender.GetNodeData(FSeledNode);
    vANode.IsCustomer := not vANode.IsCustomer;
    Sender.RepaintNode(FSeledNode);
  end
  else if Column = 4 then
  begin
    vANode := Sender.GetNodeData(FSeledNode);
    vANode.IsSupplier := not vANode.IsSupplier;
    Sender.RepaintNode(FSeledNode);
  end;
end;

這樣就完成了 Column 上 CheckBox 的顯示與編輯了。

B.Header上的   CheckBox

在屬性上編輯 Header \ Columns \ Column[n] \ 設定屬性 :
CheckBox = True ,顯示 CheckBox。
CheckType = ctCheckBox ,種類是 CheckBox 還有 RadioButton
CheckState = csUncheckedNormal / csCheckedNormal ,是否有勾選。
在屬性上編輯 Header \ Options 勾選 hoShowImages
在屬性上編輯 TreeOptions \ MiscOptions 勾選 toCheckSupport

完成!好像有點單調....

範例程式:
test_FilterCust.7z


[不要忘記 CheckBox & VirtualStringTree / VirtualTreeView]

沒有留言: