Delphi cxtreelist遍历节点 [英] Delphi cxtreelist looping through nodes

查看:443
本文介绍了Delphi cxtreelist遍历节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含3列的tcxTreeList,第一列的set属性为
Node.CheckGroupType:= ncgCheckGroup; ,第二列包含第一列的键根节点,第三列包含根节点下所有子节点的键。
如何获取根节点的密钥(是否已选中)以及将所有已检查的子节点的密钥放入2个变量中以插入db并从我们从数据库中获得的密钥中加载项

I have a tcxTreeList with 3 columns the first column has set property of Node.CheckGroupType := ncgCheckGroup;, and 2nd column contains Key of the First root node and third column contains the keys of all child nodes under the root node. How can i get the key of root node whether it is checked or not and keys of all checked child nodes into 2 variables to insert into db and Load back items from keys we get from DB

我添加项目的代码如下

 APNode := tv.Add;
 APNode.CheckGroupType := ncgCheckGroup;
 APNode.Values[0] := define;
 ApNode.Values[1] := dCode;

定义-包含诸如Created,Release,In-Active等文本。所有Root节点
dcode-包含每个根节点的键值,例如E,F,I,P,R

define - contains Text like Created, Released,In-Active etc.. all Root nodes dcode - contains key value of each root node like E,F,I,P,R

这是我为每个根节点添加子节点的方式

This is how i added child nodes for each root node

procedure TF_Form1.addPStatsToTreeList(tl: TcxTreeList; const dcode, define: string);
  function AddTreeListNode(TreeList: TcxTreeList; APNode: TcxTreeListNode; const AValues: Array of Variant; AImageIndex: Integer): TcxTreeListNode;
  begin
    Result := TreeList.AddChild(APNode);
    Result.AssignValues(AValues);
    Result.Imageindex := AImageIndex;
  end;
var
  grpnode,chNode, ANode: TcxTreeListNode;
  icnt : integer;
begin
  icnt := tl.Count;
  if Assigned(tl) then
  begin
    ANode := tl.TopNode;
    while ANode <> nil do
    begin
      ANode :=  AddTreeListNode(tl, ANode, [define, '', dcode], 0);
      ANode := TcxTreeListNode(ANode.GetNext);
    end;
  end;
end;

更新

dcode是单个字母,Definition是字符串,Dcode是定义字符串的键,就像键值对一样,Dcode是键,定义是值。
在树形列表中,根节点(如创建,发布,处于活动,已检查和重新激活)具有不同的密钥(位于第1列),而子节点值(如样本,开发,生产等)的密钥位于第3列。
仅将键值保存到DB,无论是否选中根节点键,都直接保存。每个根节点密钥将保存到不同的行中,并且仅进入子节点,而选中的节点密钥则以逗号分隔的形式保存到DB。
例如。如果选中了创建的根节点及其下的项目(如Sample,Development),则根节点键 E 是一列[DEFCODE(Primarykey)],子节点键逗号分隔的M,E (定义)在其他列中。

dcode is a single letter and Definition is a string, Dcode is the key for string in definition, Like a key-value pair Dcode is key and definition is value. In the tree list root nodes like Created, Released, In Active, Checked and Reactivated have different Key which is in column1 and key for subnode values like Sample, Development, Production etc.. is in 3rd column. Only Key values are saved to DB, root node keys are saved directly whether they are Checked or not. Each root node key will be saved to different rows and coming to subnodes only Checked nodes keys are saved to DB with comma separated. For Example . If Root node Created and items under it like Sample , Development are checked then root node key E is one column[DEFCODE(Primarykey)] and subnodes keys M,E (DEFINITION) with coma separated are in other column.

推荐答案

下面的代码显示如何将根节点的Checked状态及其
密钥及其子项的密钥列表(使用
的SaveTreeState方法进行检查)保存到TClientDataSet。

The code below shows how to save to a TClientDataSet the Checked state of a root node along with its key and a comma-separated list of the keys of its children which are checked using the method SaveTreeState.

LoadTreeState方法清除ctTreeList
中每个节点的Checked状态,然后从CDS重新加载已保存的Checked状态。

The method LoadTreeState clears the Checked state of each node in the ctTreeList and then re-loads the saved Checked states from the CDS.

要使用此代码,您需要向项目中添加名为CDS1的TClientDataSet,
以及以常规方式连接的TDataSource和TDBGrid。然后,按照代码所示,将持久性
字段添加到CDS中,进行编译并运行。

To use this code you need to add a TClientDataSet named CDS1 to your project, and a TDataSource and TDBGrid wired up in the usual way. Then add persistent fields to the CDS as shown in the code, compile and run.

我希望我已经了解了如何正确设置cxTreeList,但是如果没有,希望
的代码应该非常简单,以适应您的实际工作。

I hope I've understood how your cxTreeList is set up correctly, but if not, hopefully the code should be pretty straightforward to adapt to what you are actually doing.

type
  TForm1 = class(TForm)
    cxTreeList1: TcxTreeList;
    CDS1: TClientDataSet;
    btnLoad: TButton;
    cxTreeList1Column1: TcxTreeListColumn;
    cxTreeList1Column2: TcxTreeListColumn;
    cxTreeList1Column3: TcxTreeListColumn;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    CDS1RootKey: TStringField;    // String[1]
    CDS1CheckedChildKeys: TStringField;  //  String[20]
    CDS1RootNodeChecked: TBooleanField;
    btnClear: TButton;
    procedure btnClearClick(Sender: TObject);
    procedure btnLoadClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure SaveTreeState;
    procedure ClearChecks;
    procedure LoadTreeState;
  end;

[...]
procedure TForm1.ClearChecks;
var
  i,
  j : Integer;
begin
  for i := 0 to cxTreeList1.Count - 1 do begin
    cxTreeList1.Items[i].Checked := False;
    for j := 0 to cxTreeList1.Items[i].Count - 1 do begin
      cxTreeList1.Items[i].Items[j].Checked := False;
    end;
  end;
end;

procedure TForm1.SaveTreeState;
var
  i,
  j : Integer;
  RootNode,
  ChildNode : TcxTreeListNode;
  RootKey,
  ChildKeys : String;
begin
  CDS1.DisableControls;
  try
    CDS1.EmptyDataSet;

    for i := 0 to cxTreeList1.Count - 1 do begin
      RootNode := cxTreeList1.Items[i];
      RootKey := RootNode.Values[1];
      ChildKeys := '';
      for j := 0 to RootNode.Count - 1 do begin
        ChildNode := RootNode.Items[j];
        if ChildNode.Checked then begin
          if ChildKeys <> '' then
            ChildKeys := ChildKeys + ',';
          ChildKeys := ChildKeys + ChildNode.Values[2];
        end;
      end;
      CDS1.InsertRecord([RootKey, ChildKeys, RootNode.Checked]);
    end;
  finally
    CDS1.EnableControls;
  end;
end;

procedure TForm1.LoadTreeState;
var
  RootKey,
  ChildKey : String;
  ChildKeys : TStringList;
  i : Integer;
  RootNode,
  ChildNode : TcxTreeListNode;

  function FindRootNodeByKey(const Key : String) : TcxTreeListNode;
  var
    i : Integer;
  begin
    for i := 0 to cxTreeList1.Count - 1 do begin
      Result := cxTreeList1.Items[i];
      if CompareText(Result.Values[1], Key) = 0 then
        Exit;
    end;
    Result := Nil;
  end;

  function FindChildNodeByKey(ParentNode : TcxTreeListNode; const Key : String) : TcxTreeListNode;
  var
    i : Integer;
  begin
    for i := 0 to ParentNode.Count - 1 do begin
      Result := ParentNode.Items[i];
      if CompareText(Result.Values[2], Key) = 0 then
        Exit;
    end;
    Result := Nil;
  end;

begin
  cxTreeList1.BeginUpdate; // prevent treelist from updating while we load its state
  ClearChecks;
  try
    //  ChildKeys is a TStringList that we'll use to parse the list of child keys into individual values
    ChildKeys := TStringList.Create;
    try
      CDS1.DisableControls;
      try
        CDS1.First;
        while not CDS1.Eof do begin
          RootKey := CDS1RootKey.AsString;
          RootNode := FindRootNodeByKey(RootKey);
          Assert(RootNode <> Nil);  // check that we found the root node
          RootNode.Checked := CDS1RootNodeChecked.AsBoolean;
          ChildKeys.CommaText := Trim(CDS1CheckedChildKeys.AsString);  // Loading ChildKeys 
          //  by this assignment is what causes it to be parsed into individual keys
          for i := 0 to ChildKeys.Count - 1 do begin
            ChildKey := ChildKeys[i];
            ChildNode := FindChildNodeByKey(RootNode, ChildKeys[i]);
            Assert(ChildNode <> Nil);
            ChildNode.Checked := True;
          end;
          CDS1.Next;
        end;
      finally
        CDS1.EnableControls;
      end;
    finally
      ChildKeys.Free;
    end;
  finally
    cxTreeList1.EndUpdate;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  CDS1.CreateDataSet;
  ClearChecks;
end;

procedure TForm1.btnClearClick(Sender: TObject);
begin
  ClearChecks;
end;

procedure TForm1.btnLoadClick(Sender: TObject);
begin
  LoadTreeState;
end;

procedure TForm1.btnSaveClick(Sender: TObject);
begin
  SaveTreeState;
end;

end.

这篇关于Delphi cxtreelist遍历节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆