Home > Enterprise >  How to load TTreeView items from database along with its items image index
How to load TTreeView items from database along with its items image index

Time:06-13

I have saved my TreeView inside my DataBase by using the next :

var
BlobField :TField;
Query:TADOQuery;
Stream:TStream;
...



 try
    Query.SQL.Text := 'Select TOP(1) * From MyTable';
    DBQueryConnect(Query); // I used this Procedure to connect the Query to the database
    try
      Query.First;
      Query.Edit;
      try
        BlobField := Query.FieldByName('MyField') as TField;
        Stream := Query.CreateBlobStream(BlobField, bmWrite);
        try
          MyTreeView.SaveToStream(Stream,TEncoding.UTF8);
        finally
          Stream.Free;
        end;
        Query.Post;
      except
        Query.Cancel;
        raise;
      end;
    finally
      Query.Close;
    end;
  finally
    Query.Free;
  end;
end;

and I loaded back the TTreeView form the DataBase by using the next :

...
var
Query:TADOQuery;
Stream:TStream;
begin

      Query:=TADOQuery.Create(Self);
      try
      Query.SQL.Add('Select * From MyTable') ;
      DBQueryConnect(Query);
      Query.First;
      Stream:=Query.CreateBlobStream(Query.FieldByName('MyField'), bmread);
      MyTreeView.LoadFromStream(Stream);
      Stream.Free;
      finally
      Query.Free;
      end;

how can I retrive the imageindex for my TreeView items from the saved data .. Thank you .

CodePudding user response:

Perharps we can modify exsisting SaveTreeToStream and LoadTreeFromStream like this :

function GetBufStart(Buffer,idxSeparator: string; var Level,ImageIndex: Integer): string;
var
  Pos: Integer;
  sidx:String;
begin
  Pos := 1;
  Level := 0;
  ImageIndex := -1;
  while (CharInSet(Buffer[Pos], [' ', #9])) do
  begin
    Inc(Pos);
    Inc(Level);
  end;
  Result := Copy(Buffer, Pos, Length(Buffer) - Pos   1);
  //Check Image Index
  pos:=System.SysUtils.AnsiPos(idxSeparator,Result);
  if Pos>0 then begin
    sidx:=copy(result,Pos   Length(idxSeparator), length(result) - Pos   1);
    ImageIndex := StrToIntDef(sidx,-1);
    Result := Copy(Result, 1, Pos - 1);
  end;
end;

procedure LoadTreeFromStream(Nodes:TTreeNodes; Stream:TStream; Encoding:TEncoding; idxSeparator:String='|||');
var
  List: TStringList;
  ANode, NextNode: TTreeNode;
  ALevel, i, ImageIndex: Integer;
  CurrStr: string;
begin
  List := TStringList.Create;
  Nodes.BeginUpdate;
  try
    try
      Nodes.Clear;
      List.LoadFromStream(Stream, Encoding);
      ANode := nil;
      for i := 0 to List.Count - 1 do
      begin
        CurrStr := GetBufStart(PChar(List[i]), idxSeparator, ALevel, ImageIndex);

        if ANode = nil then
          ANode := Nodes.AddChild(nil, CurrStr)
        else if ANode.Level = ALevel then
          ANode := Nodes.AddChild(ANode.Parent, CurrStr)
        else if ANode.Level = (ALevel - 1) then
          ANode := Nodes.AddChild(ANode, CurrStr)
        else if ANode.Level > ALevel then
        begin
          NextNode := ANode.Parent;
          while NextNode.Level > ALevel do
            NextNode := NextNode.Parent;
          ANode := Nodes.AddChild(NextNode.Parent, CurrStr);
        end
        else raise Exception.CreateFmt('Invalid level (%d) for item "%s"', [ALevel, CurrStr]);
        ANode.ImageIndex:=ImageIndex;
      end;
    finally
      Nodes.EndUpdate;
      List.Free;
    end;
  except
    Nodes.Owner.Invalidate;  // force repaint on exception
    raise;
  end;
end;

procedure SaveTreeToStream(Nodes:TTreeNodes; Stream:Tstream; Encoding:TEncoding; idxSeparator:String='|||');
const
  TabChar = #9;
  EndOfLine = #13#10;
var
  I: Integer;
  ANode: TTreeNode;
  NodeStr: TStringBuilder;
  Buffer, Preamble: TBytes;
begin
  if Nodes.Count > 0 then
  begin
    if Encoding = nil then
      Encoding := TEncoding.Default;
    //Buffer := Encoding.GetBytes('');
    Preamble := Encoding.GetPreamble;
    if Length(Preamble) > 0 then
      Stream.WriteBuffer(Preamble{$IFNDEF CLR}[0]{$ENDIF}, Length(Preamble));

    NodeStr := TStringBuilder.Create(1024);
    try
      ANode := Nodes[0];
      while ANode <> nil do
      begin
        NodeStr.Length := 0;
        for I := 0 to ANode.Level - 1 do
          NodeStr.Append(TabChar);
        NodeStr.Append(ANode.Text);
        NodeStr.Append(idxSeparator);
        NodeStr.Append(ANode.ImageIndex);
        NodeStr.Append(EndOfLine);
        Buffer := Encoding.GetBytes(NodeStr.ToString);
        Stream.Write(Buffer{$IFNDEF CLR}[0]{$ENDIF}, Length(Buffer));
        ANode := ANode.GetNext;
      end;
    finally
      NodeStr.Free;
    end;
  end;
end;

You can replace MyTreeView.SaveToStream(Stream,TEncoding.UTF8); with SaveTreeToStream(MyTreeView.Items,Stream,TEncoding.UTF8); and MyTreeView.LoadFromStream(Stream); with LoadTreeFromStream(MyTreeView.Items,Stream,TEncoding.UTF8);

  • Related