I am pretty new to delphi development, I have a custom CheckTreeList component inherited from cxTreeList Devexpress component. When i check some nodes in a list, Those values are stored to a string in a format as shown below String Format for selected nodes as image The issue is I am not able to check the nodes of the checktreelist by looping through the nodes and values in the string. I have tried the below code for saving and loading the checked and unchecked nodes. Saving the checked node key values to string is working, But Loading the nodes and checking them is not working. The below is the component source code
unit DXCheckTreelist;
interface
uses
System.Classes, cxTL, cxLookAndFeelPainters;
type
TdxUnboundTreeListNode = class(TcxUnboundTreeListNode)
protected
procedure SetCheckState(AValue: TcxCheckBoxState); override;
end;
TdxCheckTreeList = class(TcxTreeList)
Private
FEnableStdTreebehaviour : Boolean;
protected
function CreateNode: TcxTreeListNode; override;
Published
Property EnableStdTreebehaviour: Boolean read FEnableStdTreebehaviour write FEnableStdTreebehaviour default False;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('DX Components', [TdxCheckTreeList]);
end;
{ TdxCheckTreeList }
function TdxCheckTreeList.CreateNode: TcxTreeListNode;
begin
Result := TdxUnboundTreeListNode.Create(Self);
Changes := Changes + [tcStructure];
end;
{ TdxUnboundTreeListNode }
procedure TdxUnboundTreeListNode.SetCheckState(AValue: TcxCheckBoxState);
var
ParentNode : TdxUnboundTreeListNode;
PrevCheckState: TcxCheckBoxState;
const
AState: array[TcxCheckBoxState] of TcxTreeListNodeCheckInfos = ([], [nciChecked], [nciGrayed]);
AParentCheckState: array[Boolean] of TcxCheckBoxState = (cbsGrayed, cbsChecked);
begin
if TdxCheckTreeList(TreeList).FEnableStdTreebehaviour then
begin
inherited;
Exit;
end;
if not CanChecked then
begin
State := State - [nsCheckStateInvalid];
Exit;
end;
PrevCheckState := CheckState;
CheckInfo := CheckInfo - [nciChecked, nciGrayed] + AState[AValue] + [nciChangeCheck];
try
if (CheckState in [cbsChecked, cbsUnchecked]) and HasChildren then
begin
LoadChildren;
if AValue = cbsUnchecked then
SetChildrenCheckState(CheckState, nil);
end;
ParentNode := TdxUnboundTreeListNode(Parent);
if ParentNode <> nil then
begin
if ParentNode.IsRadioGroup and Checked then
ParentNode.SetChildrenCheckState(cbsUnchecked, Self);
if not (nciChangeCheck in ParentNode.CheckInfo) and (ParentNode <> Root) then
ParentNode.CheckState := cbsChecked;
end;
finally
CheckInfo := CheckInfo - [nciChangeCheck];
State := State - [nsCheckStateInvalid];
if CanChecked then
Repaint(True);
if (PrevCheckState <> CheckState) and Assigned(TcxTreeList(TreeList).OnNodeCheckChanged) then
TcxTreeList(TreeList).OnNodeCheckChanged(TreeList, Self, CheckState);
end;
end;
end.
In my case the property EnableStdTreebehaviour is set to true.
Code for saving selected node key values is
procedure TfrmTreeList.btnSaveDataClick(Sender: TObject);
var
I, J: Integer;
node, cnode: TcxTreeListNode;
Result: String;
begin
result:= '';
for i := 0 to ctvMandatory.Count - 1 do
begin
node := TcxTreeListNode(ctvMandatory.Items[i]);
if ctvMandatory.Items[i].CheckState in [cbsChecked, cbsGrayed] then
begin
if node.Level = 0 then Result:= Result + '[' + node.Values[1] + ']' + ',';
for J := 0 to ctvMandatory.Items[i].Count - 1 do
begin
cnode := ctvMandatory.Items[i].Items[J];
if (cnode.Checked) and (cnode.Level = 1) then
begin
Result:= Result + cnode.Values[2] + ',';
end;
end;
end;
end;
if (Result <> '') and (Result[Length(result)] = ',') then
result:= Copy(Result, 1, length(Result) -1 );
Memo.Clear;
if result <> '' then
begin
Memo.Lines.Add(Trim(Result));
csv := result;
end;
for i := 0 to ctvMandatory.count - 1 do
begin
node := TcxTreeListNode(ctvMandatory.Items[i]);
ctvMandatory.Items[i].Checked := False;
end;
end;
Code i tried for loading and check node depend on keyvalue from string is
procedure TfrmTreeList.btnLoadDataClick(Sender: TObject);
var
i, j, X: integer;
node, cnode: TcxTreeListNode;
sl,s2: TStringList;
str: string;
key, value, val: string;
begin
chbAll.Checked:= csv = 'All';
ctvMandatory.BeginUpdate;
if chbAll.Checked then
begin
for i:= 0 to ctvMandatory.AbsoluteCount - 1 do
ctvMandatory.Items[I].Checked := True;
ctvMandatory.EndUpdate;
SetMandatoryText;
Exit;
end;
for i:= 0 to ctvMandatory.Count - 1 do
ctvMandatory.Items[I].Checked := False;
if csv = 'All' then
begin
for i:= 0 to ctvMandatory.AbsoluteCount - 1 do
ctvMandatory.Items[I].Checked := True;
end
else
if (length(csv) > 0) and (Pos(']', csv) = 0) then
begin
for i := 0 to ctvMandatory.Count - 1 do
begin
node:= TcxTreeListNode(ctvMandatory.Items[i]);
if node.Level = 0 then
ctvMandatory.Items[i].Checked:= True
else
if (node.Level = 1) and IsValueInCSV(csv, node.Values[1]) then
begin
ctvMandatory.Items[i].Checked := True;
end;
end;
end
else
begin
sl:= TStringList.Create;
sl.Delimiter:= ',';
sl.DelimitedText:= csv;
node:= nil;
s2:= TStringList.Create;
s2.Delimiter:= ',';
for str in sl do
begin
if (pos('[', str) > 0) then
begin
if (value <> '') and (value[Length(value)] = ',') then
value := Copy(value, 1, length(value) -1);
s2.DelimitedText:= value;
if (node <> nil) and (value <> '') and (node.HasChildren) then
begin
for I := 0 to ctvMandatory.Count - 1 do
begin
while Node <> Nil do
begin
node:= TcxTreeListNode(ctvMandatory.Items[I]);
node:= node.getFirstChild;
if not node.Checked then
begin
val := '';
for val in s2 do
begin
node.Checked := true;
node.getNextSibling;
end;
end;
s2.Clear;
end;
end;
end;
value:= '';
val := '';
key:= ReplaceStr(str, '[', '');
key:= ReplaceStr(key, ']', '');
for I := 0 to ctvMandatory.Count - 1 do
begin
if (TcxTreeListNode(ctvMandatory.Items[i]).Values[1] = key) and ((ctvMandatory.Items[i]).Level = 0) then
begin
node:= TcxTreeListNode(ctvMandatory.Items[i]);
Break;
end;
end;
end
else
begin
value:= value + str + ',';
end;
end;
if (value <> '') and (value[Length(value)] = ',') then
value := Copy(value, 1, length(value) -1);
s2.DelimitedText:= value;
if (node <> nil) and (value <> '') and (node.HasChildren) then
begin
for I := 0 to ctvMandatory.Count - 1 do
begin
while Node <> Nil do
begin
node:= TcxTreeListNode(ctvMandatory.Items[I]);
node:= node.getFirstChild;
if not node.Checked then
begin
val := '';
for val in s2 do
begin
node.Checked := true;
node.getNextSibling;
end;
end;
s2.Clear;
end;
end;
end;
sl.Free;
s2.Free;
end;
ctvMandatory.EndUpdate;
SetMandatoryText;
end;
function TfrmTreeList.IsValueInCSV(const CSV, Value: string): Boolean;
begin
Result := IsValueInCSV(CSV, Value, False);
end;
function TfrmTreeList.IsValueInCSV(const CSV, Value: string; ResultIfBothEmpty: Boolean): Boolean;
begin
if Trim(CSV) = Trim(Value) then
begin
if Trim(Value) = '' then
Result := ResultIfBothEmpty
else
Result := True;
end
else
Result := MatchStr(Value, SplitString(CSV, ','));
end;
Can some please check and help me on this issue?
[RT1],R,M,Y,[RT2],L,S,K,[RT3],A,U,B,[RT4],R,S,B, In this string [RT1], [RT2], [RT3], [RT4] are keys of rootnode, the remaining are Checked ChildNode keyvalues present under that rootnode - HelloUser