首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder TTreeView 節點啟用/禁用完整實作指南

     編輯:關於C++

前言

TTreeView 的 TTreeNode 無內建 Enabled 屬性。本文實作完整的節點禁用機制:灰色字體顯示 + 禁止選取,透過 Data 屬性標記狀態、OnCustomDrawItem 自繪、OnChanging 攔截選取。

核心設計

  • 狀態標記:使用 Node->Data(void*),NULL=啟用,(void*)0xFFFF=禁用
  • 視覺回饋:OnCustomDrawItem 事件中依狀態設定 Canvas->Font->Color = clGray
  • 互動控制:OnChanging 事件中檢查目標節點狀態,設定 AllowChange

完整實作程式碼

1. 狀態切換輔助函數


// 改變指定節點的啟用/禁用狀態
// bEnable: true=啟用, false=禁用
// pNode: 目標節點
void __fastcall CrnEnableTreeNode(bool bEnable, TTreeNode* pNode) {
    // 規則:啟用時 Data=NULL,禁用時 Data=0xFFFF
    pNode->Data = bEnable ? NULL : (void*)0xFFFF;
    // 強制重繪 TreeView 更新視覺
    pNode->TreeView->Invalidate();
}

2. 自繪事件:灰色顯示禁用節點


void __fastcall TForm1::TreeView1CustomDrawItem(
    TCustomTreeView* Sender, TTreeNode* Node,
    TCustomDrawState State, bool& DefaultDraw) {
    
    // 檢查節點是否被禁用
    if ((int)Node->Data == 0xFFFF) {
        // 禁用節點:灰色字體
        Sender->Canvas->Font->Color = clGray;
    }
    // DefaultDraw=true 讓系統繼續預設繪製流程
}

3. 選取攔截事件:禁止選中禁用節點


void __fastcall TForm1::TreeView1Changing(
    TObject* Sender, TTreeNode* Node, bool& AllowChange) {
    
    // 即將選中 Node 時檢查狀態
    AllowChange = ((int)Node->Data != 0xFFFF);
    // 禁用節點 → AllowChange=false → 取消選取變更
}

測試程式碼


void __fastcall TForm1::Button1Click(TObject* Sender) {
    // 禁用目前選中的節點
    if (TreeView1->Selected) {
        CrnEnableTreeNode(false, TreeView1->Selected);  // false = 禁用
    }
}

void __fastcall TForm1::Button2Click(TObject* Sender) {
    // 啟用第二個節點(索引 1)
    CrnEnableTreeNode(true, TreeView1->Items->Item[1]);  // true = 啟用
}

效果展示

TreeView 節點禁用效果展示

禁用節點呈現灰色字體,滑鼠點擊無法選中,鍵盤導航也會跳過。

進階考量

若 Data 屬性已被佔用

改用其他標記方式:

  • 子類別 TTreeNode 加入 bool Enabled 欄位
  • 使用 TDictionary<TTreeNode*, bool> 外部映射
  • 利用 Node->Index + Node->Level 組合鍵查找外部狀態表

擴充:禁用整個子樹


void DisableSubTree(TTreeNode* root, bool disable) {
    CrnEnableTreeNode(!disable, root);
    for (int i = 0; i < root->Count; ++i) {
        DisableSubTree(root->Item[i], disable);
    }
}

樣式微調:禁用節點加上斜體


if ((int)Node->Data == 0xFFFF) {
    Sender->Canvas->Font->Color = clGray;
    Sender->Canvas->Font->Style = TFontStyles() << fsItalic;
}

適用版本與注意事項

  • 適用:C++Builder 6 及以上(含 VCL for Win32)
  • OnCustomDrawItem 需 TreeView->CustomDraw = true(設計時勾選)
  • Invalidate() 觸發重繪,大量節點頻繁切換時可考慮 BeginUpdate/EndUpdate
  • 禁用節點仍可程式碼存取(TreeView->Selected = disabledNode 會被 OnChanging 攔截)

總結

透過 Data 屬性標記、OnCustomDrawItem 視覺回饋、OnChanging 互動攔截三步驟,即可為 TTreeView 實作完整的節點啟用/禁用功能。此法無需繼承元件、相容性佳、擴充性強,適合企業級應用的樹狀介面權限控制需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved