你可以去精华区,那里介绍了加checkbox的treeview控件,很详细的。

解决方案 »

  1.   

    有一个现成的,参考一下吧TreeView有个Images属性,做三张小图片:
    全选中、部分选中、不选状态(直接拍下CheckBox三种状态的图片在加工一下就可以了),然后在点击事件中根据具体情况设置TTreeNodes的ImageIndex就OK了。
    重载TreeView的CreateParams:
    type
      TCheckBoxTreeView = class(TTreeView)
      protected
        procedure CreateParams(var Params: TCreateParams); override;
      end;procedure TCheckBoxTreeView.CreateParams(var Params: TCreateParams);
    begin
      inherited;
      Params.Style:=Params.Style or TVS_CHECKBOXES;
      { TVS_CHECKBOXES declared in CommCtrl }
    end;如果要Check这个CheckBox,可以用下面的代码:
    function IsNodeChecked(Node :TTreeNode) :Boolean;
    const
      TVIS_CHECKED = $2000;
    var
      TvItem :TTVItem;
    begin
      TvItem.Mask  := TVIF_STATE;
      TvItem.hItem := Node.ItemId;
      TreeView_GetItem(Node.TreeView.Handle, TvItem);
      Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;
    end;procedure SetNodeChecked(Node :TTreeNode; Checked :Boolean);
    const
      TVIS_CHECKED = $2000;
    var
      TvItem :TTVItem;
    begin
      FillChar(TvItem, SizeOf(TvItem), 0);
      with TvItem do begin
        hItem     := Node.ItemId;
        Mask      := TVIF_STATE;
        StateMask := TVIS_STATEIMAGEMASK;
        if Checked then
          TvItem.State :=TVIS_CHECKED
        else
          TvItem.State :=TVIS_CHECKED shr 1;
        TreeView_SetItem(Node.TreeView.Handle, TvItem);
      end;
    end;
    可以做成事件和封装成一个类:
    private OldState :Boolean;procedure Change(Node: TTreeNode); override;
    begin
      inherited Change(Node);
      OldState := IsNodeChecked(Node);
    end;procedure Click; override;
    var
      NewState :Boolean;
    begin
      inherited Click;
      NewState := IsNodeChecked(Self.Selected);
      if NewState = OldState then Exit;
      if (NewState) and Assigned(OnNodeChecked) then OnNodeChecked()
      else if (not NewState) and Assigned(OnNodeUnChecked) then
    OnNodeUnChecked()// OnNodeChecked & OnNodeUnchecked will be events that you declare
    end;