Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Virtualstringtree suchen mit Child-Nodes (https://www.delphipraxis.net/177035-virtualstringtree-suchen-mit-child-nodes.html)

HPB 11. Okt 2013 11:20

Virtualstringtree suchen mit Child-Nodes
 
Guten Tag Delphianer,
folgendes Problem mit der Suche im Virtualstringtree bekomme ich nicht gelöst:
Beim Suchen werden werden die Child-Nodes nicht mehr angezeigt.:cry::cry::cry::cry:
Der Aufbau ist Ordnung. Es werden die Nodes auch richtig aufgebaut. D. H. Parent-Node und Child-Node werden korrekt angezeigt.Beim Expand der Nodes werden die Child-Nodes auch richtig angezeigt.
---------------------------------------------------------------------------------------


Die beiden Records aus denen das VST aufgebaut wird.
Delphi-Quellcode:
  TOVSTAngebote = class(TObject)
  public
    FPKAngebotsNr: string;
    FAngebotstitel: string;
    FKuSuchCode: string;
    FKundenNr: string;
    FAdressID: LongInt;
    FSuchCode: string;
    FName: string;
    FAGGedruckt: string;
    FKostenStelle: string;
    FfNetto: Currency;
    FfMwst: Currency;
    FfBrutto: Currency;
    FDatum: TDateTime;
    FPauschal: string;
    FfPauschalPreis: Currency;
    FfMenge: double;
    FAbgerechnet: string;
  end;

  //============================================================================
  // Dokumentenklasse für Angebote Anzeige im VST
  //============================================================================
  TOAngeboteDokumente = class(TOVSTAngebote)
  public
    FDokumentName: string;
    FAdressOrdner: string;
    FDokumentWert: Currency;
    FDokumentDatum: TDateTime;
    FDokumentNr: string;
  end;
---------------------------------------------------------
Delphi-Quellcode:
procedure TOVSTFuerAngeboteAufbauen.BauVSTAuf;
var
  aAngebotsNr: string;
  pKostenstelle: string;
  pDokumentPfadName: string;
  pDokumentName: string;

  pNode1: PVirtualNode;

  pSQLDok: TIBSQL;

  angebote: TOVSTAngebote;
  pDokumente: TOAngeboteDokumente;
begin
  dmain.pStartTransAction;
  FVST.BeginUpdate;
  FVST.Clear;

  Application.CreateForm(TIBSQL, pSQLDok);

  pSQLDok.Database := DMAIN.dbmain;
  pSQLDok.Transaction := DMAIN.tranmain;

  FSQLA.Close;
  FSQLA.SQL.Clear;
  FSQLA.SQL.Add('select * from Angebote ');
  FSQLA.SQL.Add('where abgerechnet = :pAbgerechnet ');
  FSQLA.SQL.Add('and geloescht = ' + #39 + 'N' + #39);
  FSQLA.SQL.Add('and fkadressid = :pAdressID ');
  FSQLA.SQL.Add(' order by titel');
  FSQLA.Prepare;
  FSQLA.ParamByName('pAbgerechnet').Value := FAlleZeigen;
  FSQLA.ParamByName('pAdressid').Value := FAdressID;
  FSQLA.ExecQuery;

  while not FSQLA.Eof do
  begin
    aAngebotsNr := FSQLA.FieldByName('pkAngebote').AsString;
    pKostenstelle := FSQLA.FieldByName('kostenstelle').AsString;

    angebote := TOVSTAngebote.Create;
    angebote.FPKAngebotsNr := FSQLA.FieldByName('pkAngebote').AsString;
    angebote.FAngebotstitel := FSQLA.FieldByName('titel').AsString;
    angebote.FAdressID := FSQLA.FieldByName('fkadressid').AsInt64;
    angebote.FSuchCode := FSQLA.FieldByName('suchcode').AsString;
    angebote.FName := FSQLA.FieldByName('ReName').AsString;
    angebote.FfNetto := FSQLA.FieldByName('angebotnettosumme').AsFloat;
    angebote.FfMwst := FSQLA.FieldByName('mwstbetrag').AsFloat;
    angebote.FfBrutto := FSQLA.FieldByName('bruttobetrag').AsFloat;
    angebote.FDatum := FSQLA.FieldByName('datum').AsDateTime;
    angebote.FKostenStelle := FSQLA.FieldByName('kostenstelle').AsString;
    angebote.FAbgerechnet := FSQLA.FieldByName('abgerechnet').AsString;

    pNode1 := FVST.AddChild(nil, angebote);

    if pKostenstelle <> '' then
    begin
      pSQLDok.Close;
      pSQLDok.SQL.Clear;
      pSQLDok.SQL.Add('select * from alledokumente ');
      pSQLDok.SQL.Add('where fkadressid = :pAdressID ');
      pSQLDok.SQL.Add('and kostenstelle = :pKostenStelle');
      pSQLDok.SQL.Add('order by dokumenttyp ');
      pSQLDok.Prepare;
      pSQLDok.ParamByName('pAdressID').Value := FAdressID;
      pSQLDok.ParamByName('pKostenStelle').Value := pKostenstelle;
      pSQLDok.ExecQuery;
      while not pSQLDok.Eof do
      begin
        pDokumentPfadName := pSQLDok.FieldByName('dokumentPfad').AsString;
        pDokumentName := pSQLDok.FieldByName('dokumentName').AsString;

        pDokumente := TOAngeboteDokumente.Create;
        pDokumente.FDokumentName := pDokumentName;
        pDokumente.FAdressOrdner := IntToStr(FAdressID);
        pDokumente.FDokumentWert :=
          pSQLDok.FieldByName('rebetrag').AsCurrency;
        pDokumente.FDokumentDatum :=
          pSQLDok.FieldByName('dokumentdatum').AsDateTime;
        pDokumente.FDokumentNr := pSQLDok.FieldByName('dokumentnr').AsString;
       
        FVST.AddChild(pNode1, pDokumente);

        pSQLDok.Next;
      end;
    end;
    FSQLA.Next;
  end; // alle angebote

  pSQLDok.Close;
  pSQLDok.Free;
  FSQLA.Close;
  FSQLA.Free;
  FVST.EndUpdate;
  dmain.tranmain.CommitRetaining;
end;
--------------------------------------------------------------------------

Aufbau des VST:
Delphi-Quellcode:
procedure TMSFrmAngebote.vstAngeboteGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
var
  pDaten: TOVSTAngebote;
begin
  pDaten := TOVSTAngebote(vstangebote.GetNodeData(Node)^);
  case column of
    0:
      begin
        if pDaten is TOVSTAngebote then
          celltext := TOVSTAngebote(pDaten).FAngebotstitel
            + ' (' + TOVSTAngebote(pDaten).FPKAngebotsNr + ')';

        if pDaten is TOAngeboteDokumente then
          CellText := TOAngeboteDokumente(pDaten).FDokumentName;
      end;
    1:
      begin
        if pDaten is TOVSTAngebote then
          CellText := TOVSTAngebote(pDaten).FSuchCode;
      end;
    2:
      begin
        if pDaten is TOVSTAngebote then
          celltext := FormatDatetime('dd.mm.yyyy',
            TOVSTAngebote(pDaten).FDatum);
        if pDaten is TOAngeboteDokumente then
        begin
          pJahr := ZerlegeJahr(TOAngeboteDokumente(pDaten).FDokumentDatum);
          if pJahr <> 1899 then
            CellText := FormatDatetime('dd.mm.yyyy',
              TOAngeboteDokumente(pDaten).FDokumentDatum);
        end;
      end;
    3:
      begin
        if pDaten is TOVSTAngebote then
          Celltext := FloatToStrF(TOVSTAngebote(pDaten).FfBrutto, ffCurrency, 8,
            2);
        if pDaten is TOAngeboteDokumente then
          CellText := FloatToStrF(TOAngeboteDokumente(pDaten).FDokumentWert,
            ffCurrency, 8, 2);
      end;
  end;
end;
------------------------------------------------------------------------------
Gesucht wird über ItereeSubTree, über das OnChange-Ereignis eines Editfeldes.
Die gefundenen Nodes werden angezeigt. Die Parent-Nodes haben auch ein Pluszeichen für das Aufklappen,
aber beim Klick auf das Pluszeichen sind die Child-Daten nicht vorhanden!:?::?::?:
Warum nicht???

Delphi-Quellcode:
procedure TMSFrmAngebote.SucheCallback(Sender: TBaseVirtualtree;
  Node: PVirtualNode; Data: Pointer; var Abort: Boolean);
var
  cSuche: string;
  pDaten: TOVSTAngebote;
begin
  cSuche := AnsiUpperCase(edtSuche.Text);
  pDaten := TOVSTAngebote(vstangebote.GetNodeData(Node)^);

  case AdvOfficeRadioGroupSuchenach.ItemIndex of
    0:
      begin
        vstangebote.IsVisible[Node] := (cSuche = '')
          or (pos(cSuche,
          AnsiUpperCase(pDaten.FAngebotstitel)) > 0);
      end;
    1:
      begin
        vstangebote.IsVisible[Node] := (cSuche = '')
          or (pos(cSuche, pDaten.FSuchCode) > 0);
      end;
  end;
end;
---------------------------------------------------
Hat jemand eine Lösung für dieses Problem? Wie kann ich dieses Problem lösen??:shock:
Mit Gruß
HPB

generic 11. Okt 2013 12:35

AW: Virtualstringtree suchen mit Child-Nodes
 
Ich würde meinen die Unterknoten sind mit isVisible abgeschaltet und der Aufklapper wurde noch gecached angezeigt.

Mit IterateTree wird durch alle Knoten gegangen.

Willst du nur die Hauptknoten ausblenden?
Dir fehlt im Callback eine Prüfung auf den Datentyp der Daten.

HPB 11. Okt 2013 14:20

AW: Virtualstringtree suchen mit Child-Nodes
 
Zitat:

Zitat von generic (Beitrag 1231800)
Ich würde meinen die Unterknoten sind mit isVisible abgeschaltet und der Aufklapper wurde noch gecached angezeigt.

Mit IterateTree wird durch alle Knoten gegangen.

Willst du nur die Hauptknoten ausblenden?
Dir fehlt im Callback eine Prüfung auf den Datentyp der Daten.

Danke für Deine rasche Antwort,
wo kann ich denn die ChildNodes mit "isVisible" ein- oder ausschalten? Ich habe in den Einstellungen des VST nichts gefunden.
Nein ich möchte natürlich nicht nur die Hauptknoten ausblenden. Ich möchte das die ParentNodes gefunden werden und mit den dazugehörenden ChildNodes angezeigt werden.
Was meinst Du mit "Dir fehlt im Callback eine Prüfung auf den Datentyp der Daten"?
Kannst Du mir bitte auf die Sprünge helfen? Evtl. mit einem kleinen Beispiel:)
Ich stehe z. Z. völlig auf dem Schlauch oder sehe ich vor lauter Wald die Bäume nicht mehr:?::?:
Mit Gruß
HPB

generic 11. Okt 2013 14:42

AW: Virtualstringtree suchen mit Child-Nodes
 
Ich muss gestehen, ich habe übersehen, dass die Dokumente von dem Angebot vererbt ist.
Sorry

Allerdings hat mich der getText auf verwirrt:
Delphi-Quellcode:
var
  pDaten: TOVSTAngebote;
begin
  pDaten := TOVSTAngebote(vstangebote.GetNodeData(Node)^);
  case column of
    0:
      begin
        if pDaten is TOVSTAngebote then
          celltext := TOVSTAngebote(pDaten).FAngebotstitel
            + ' (' + TOVSTAngebote(pDaten).FPKAngebotsNr + ')';
Du castest die Daten auf den Datentyp TOVSTAngebote und prüfst ob die Variable vom Typ TOVSTAngebote Daten vom Typ TOVSTAngebote enthält, um es dann wieder auf TOVSTAngebote zu casten.


Welche Version vom VST nutzt du?

Das ermitteln des Plus Zeichen wird in der Methode DetermineHiddenChildrenFlagAllNodes gemacht.
Die wird u.a. aufgerufen, wenn du deine Suche mit BeginUpdate und EndUpdate einkapselst. Gibt da aber paar Bedingungen.

Delphi-Quellcode:
vst.beginupdate();
try
  vst.iterateSubtree(...);
finally
  vst.endupdate();
end;
Du kannst übrigens auch IsFiltered nutzen.

HPB 11. Okt 2013 15:02

AW: Virtualstringtree suchen mit Child-Nodes
 
Zitat:

Zitat von generic (Beitrag 1231810)
Ich muss gestehen, ich habe übersehen, dass die Dokumente von dem Angebot vererbt ist.
Sorry

Allerdings hat mich der getText auf verwirrt:
Delphi-Quellcode:
var
  pDaten: TOVSTAngebote;
begin
  pDaten := TOVSTAngebote(vstangebote.GetNodeData(Node)^);
  case column of
    0:
      begin
        if pDaten is TOVSTAngebote then
          celltext := TOVSTAngebote(pDaten).FAngebotstitel
            + ' (' + TOVSTAngebote(pDaten).FPKAngebotsNr + ')';
Du castest die Daten auf den Datentyp TOVSTAngebote und prüfst ob die Variable vom Typ TOVSTAngebote Daten vom Typ TOVSTAngebote enthält, um es dann wieder auf TOVSTAngebote zu casten.


Welche Version vom VST nutzt du?

Das ermitteln des Plus Zeichen wird in der Methode DetermineHiddenChildrenFlagAllNodes gemacht.
Die wird u.a. aufgerufen, wenn du deine Suche mit BeginUpdate und EndUpdate einkapselst. Gibt da aber paar Bedingungen.

Delphi-Quellcode:
vst.beginupdate();
try
  vst.iterateSubtree(...);
finally
  vst.endupdate();
end;
Du kannst übrigens auch IsFiltered nutzen.

Ich habe es einmal mit "vstBeginUpdate . . ." versucht. Bringt aber auch keine Lösung.
Ich arbeite mit der Version: 5.2.1
Ich habe mal das Cast und die erneute Prüfung herausgenommen. Auch keine Lösung.
Wo stelle ich "IsFiltered" ein. Ich habe nichts gefunden!
Übrigens ist mir folgendes noch aufgefallen:
Wenn ich alle Nodes expandiere und dann suche, werden sofort alle ChildNodes nicht mehr angezeigt:!:
Warum ist dies so:?::?:
Gruß HPB

jaenicke 11. Okt 2013 22:15

AW: Virtualstringtree suchen mit Child-Nodes
 
Ich habe jetzt nur einen ganz kurzen Blick drauf geworfen... kann es sein, dass du in SucheCallback vst.GetNodeLevel benutzen müsstest um zu schauen, ob das die oberste Ebene ist? Denn so wie ich das verstehe blendest du die Childnodes dort mit aus, obwohl du wie ich es verstehe nur die Oberknoten filtern willst.

HPB 12. Okt 2013 15:42

AW: Virtualstringtree suchen mit Child-Nodes
 
Zitat:

Zitat von jaenicke (Beitrag 1231839)
Ich habe jetzt nur einen ganz kurzen Blick drauf geworfen... kann es sein, dass du in SucheCallback vst.GetNodeLevel benutzen müsstest um zu schauen, ob das die oberste Ebene ist? Denn so wie ich das verstehe blendest du die Childnodes dort mit aus, obwohl du wie ich es verstehe nur die Oberknoten filtern willst.

Guten Tag jaenicke,
ja, das ist mir gestern aufgefallen. Mit ItereeSubTree werden ja alle Nodes durchlaufen. Dies schrieb ja auch Generic. Wenn ich nun mit Pos(...) überprüfe, dann fallen ja alle Nodes heraus, die die Bedingungen nicht erfüllen, und dies sind die Subnodes. Ich werde also prüfen ob der selektierte Node der ParentNode ist und dann sollten auch die richtigen Nodes gefunden werden.
Nochmals Dank an allen, die mit bei der Lösung behilflich waren. :thumb:
Mit Gruß HPB

Jens Hartmann 10. Mär 2016 22:15

AW: Virtualstringtree suchen mit Child-Nodes
 
Hallo zusammen,

ich habe vieleicht ein ähnliches Problem. Bei meiner Suche werden die Knoten von NodeLevel 3 nicht mehr angezeigt. Ich suche im NL 1 und 2 nach einem Ort und mache mit

Delphi-Quellcode:
vst.IsVisible[Node]
die Knoten sichtbar oder nicht.

Da ich meine Knoten unter NodeLevel 3 erst mit

Delphi-Quellcode:
vst.Expanding
erzeugen, gehe ich aktuell davon aus, dass diese aus diesem Grund nicht angezeigt werden. Mit einen Doppelklick auf einen Knoten aus NodeLevel werden die Childs aber ganz normal erzeugt.

Im
Delphi-Quellcode:
OnInit
sagen ich den Knoten unter NodeLevel 2, das Sie Childs haben...

Delphi-Quellcode:
vst.HasChildren[Node] := True;
Dadurch werden im Normalfall (bei öffnen ohne vorher die Auswahl durch die Suche eingeschränkt zu haben) vor dem Note das + zum öffnen dargestellt. Dieses ist allerdings nach der Suche nicht mehr sichtbar.

Die Childs lassen sich trotzdem wie vor beschrieben per Doppelklick öffnen.

Jemand ne Idee...

Danke schonmal und Gruß jens

Jens Hartmann 12. Mär 2016 17:35

AW: Virtualstringtree suchen mit Child-Nodes
 
Keiner nee Idee...

haentschman 13. Mär 2016 06:57

AW: Virtualstringtree suchen mit Child-Nodes
 
:P Doch... Moin...

Nachtrag: Upps... du bist ja gar nicht der TE mit der Anforderung und Quelltext aus #1... :oops: Vieleicht hilft die Idee ja trotzdem.

Ich gehe mal davon aus das du nicht hunderttausende Daten im Tree hast. Nach jedem Tastendruck in einem Suchedit soll der Tree angepaßt sein.

...dann baue den Tree einfach komplett neu auf. :thumb: Du erzeugst ja die Nodes aus Objekten welche du dann an den Node hängst. Beim Aufbau prüfst du ob die Daten in deinen Match passen (ContainsText z.B.) bei Match hängst du an... fertsch. Das geht so schnell das du das gar nicht merkst das das neu aufgebaut ist. BeginUpdate etc. darf natürlich nicht fehlen. Das Einzige was du tun mußt, ist die Liste mit den gesamten Objekten aus der SQL Abfrage vorhalten und die Abfrage und den Aufbau trennen...was sowieso sinnvoll ist.
8-)

Jens Hartmann 13. Mär 2016 14:36

AW: Virtualstringtree suchen mit Child-Nodes
 
Hallo Haentschman,

danke erstmal für Deine antwort. Grundlegend könnte ich das so aufbauen. Aber trotzdem stelle ich mir die Frage, warum das so ist. Im OnInit des VST sagen ich den Nodes doch, das Sie Childs haben.

Delphi-Quellcode:
procedure TfReportClient.vstKundenInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
  case vstKunden.GetNodeLevel(Node) of
    1:
     begin
       vstKunden.HasChildren[Node] := True;
     end;
    2:
     begin
       vstKunden.HasChildren[Node] := True;
     end;
    3:
     begin
       vstKunden.HasChildren[Node] := True;
     end;
  end;
end;
Nach dem Programmstart, ist das auch so im VST ersichtlich. Nur wenn ich suche, wird das "+"+ zum öffnen der Childs nicht mehr angezeigt. Doppelklick öffnet aber das Child.

jaenicke 13. Mär 2016 17:10

AW: Virtualstringtree suchen mit Child-Nodes
 
Das habe ich nie benutzt. Ich habe einfach immer ChildCount auf 1 gesetzt. Damit hatte ich dieses Problem bisher nicht.

Jens Hartmann 14. Mär 2016 05:32

AW: Virtualstringtree suchen mit Child-Nodes
 
Liste der Anhänge anzeigen (Anzahl: 3)
Zitat:

Zitat von jaenicke
Das habe ich nie benutzt. Ich habe einfach immer ChildCount auf 1 gesetzt. Damit hatte ich dieses Problem bisher nicht.

Aber das ergibt jetzt meiner Meinung nach keinen Sinn. Der ChildCount ist bei mir unterschiedlich. Außerdem sind die Nodes ja vorhanden. Es fehlt ja nur das + zum öffnen. Mit einem Doppelklick, öffnet sich ja dann das Node. Siehe hierzu die Bilder im Anhang...

Gruß Jens

jaenicke 14. Mär 2016 06:11

AW: Virtualstringtree suchen mit Child-Nodes
 
Ja, das ist mir schon klar. Ich habe aber nicht HasChildren gesetzt, sondern immer ChildCount auf 1. Wenn dann ausgeklappt wurde, habe ich den echten Wert für ChildCount gesetzt usw.
Das mag nicht die schönste Lösung sein, aber HasChildren hatte ich nicht gefunden und es funktioniert problemlos.

madas 14. Mär 2016 11:27

AW: Virtualstringtree suchen mit Child-Nodes
 
Zitat:

Zitat von Jens Hartmann (Beitrag 1332764)
Keiner nee Idee...

Vielleicht hilft ja ein einfaches

Delphi-Quellcode:
Tree.Expanded[Node] := True;
Tree.Expanded[Node] := False;

Jens Hartmann 14. Mär 2016 12:40

AW: Virtualstringtree suchen mit Child-Nodes
 
Zitat:

Zitat von madas
Vielleicht hilft ja ein einfaches

Das kann ich gerne ausprobieren, aber wäre doch auch irgendwie nicht die richige Lösung.

Beim suchen, prüfen ich ja immer nur im "NodeLevel 1". Daher blende ich ja "NodeLevel 2 und 3" niemals aus. Ich verstehe daher nicht, warum nach dem erstellen die "+" zeichen sichbar sind und nach dem Suchen nicht mehr. Das OnInit wird doch auch nur beim Initialieren der Nodes ausgeführt und hat daher beim suche keine relevance.

:gruebel::gruebel::gruebel:

Aviator 14. Mär 2016 19:04

AW: Virtualstringtree suchen mit Child-Nodes
 
Also ich benutze auch die Events
Delphi-Quellcode:
OnInit()
und
Delphi-Quellcode:
OnInitChildren()
und bei mir funktioniert das problemlos. Der einzige Unterschied ist, dass ich im
Delphi-Quellcode:
OnInit()
nicht die Property
Delphi-Quellcode:
HasChildren[Node]
benutze, sondern über den Var-Parameter
Delphi-Quellcode:
InitialStates
den initialen Status der Node zurückgebe. Hab mich zwar schnell mit dem Texteditor durch das Event geklickt und keine großen Auffälligkeiten gefunden was dort anders gemacht wird, aber vielleicht hilft es ja. Bei mir funktioniert es jedenfalls problemlos. Und ich benutzte einige tausende Nodes als ChildNodes die erst initialisiert werden wenn ich sie wirklich brauche.

Jens Hartmann 14. Mär 2016 21:32

AW: Virtualstringtree suchen mit Child-Nodes
 
Also bei mir klappt das auch mit dem

Delphi-Quellcode:
InitialStates := InitialStates + [ivsHasChildren];
Hier mal ein Teil des Codes...

Delphi-Quellcode:
//InitNode
procedure TfReportClient.vstKundenInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
  NodeLevel : Integer;
begin
 NodeLevel := vstKunden.GetNodeLevel(Node);
 case NodeLevel of
   1: InitialStates := InitialStates + [ivsHasChildren];
   2: InitialStates := InitialStates + [ivsHasChildren];
   3: InitialStates := InitialStates + [ivsHasChildren];
 end;
end;

//EditChange Suche
procedure TfReportClient.edtSearchChange(Sender: TObject);
begin
  vstKunden.BeginUpdate;
  vstKunden.IterateSubtree(nil, SpeedSearch, Pointer(edtSearch.Text), [], true);
  vstKunden.EndUpdate;
end;

//Methode SpeedSearch
procedure TfReportClient.SpeedSearch(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean);
var
  Kunden_Daten : PCustomersData;
  NodeLevel, i : integer;
  ws: string;
begin
  try
    NodeLevel := vstKunden.GetNodeLevel(Node);
    if NodeLevel = 1 then
      begin
        ws := string(Data);
        //Diverse Suchoptionen
        //...
        //...
        //...
        { Sucht im Kundennamen von Anfang des Strings }
        vstKunden.IsVisible[Node] :=
          (ws = '') or (pos(AnsiUpperCase(ws),
          AnsiUpperCase(TOCustomers(Kunden_Daten.FCustomer_Object).Kunden_Kundenname)) = 1);
      end
  except
    //Fehlerbehandlung
  end;
end;
Vieleicht fehlt ja irgendetwas auf...

Gruß Jens

Jens Hartmann 15. Mär 2016 20:00

AW: Virtualstringtree suchen mit Child-Nodes
 
Also wo auch immer das dran liegt. Ich bekomme es nicht in den Griff...

Noch jemand einen Vorschlag...

Jens Hartmann 15. Mär 2016 22:23

AW: Virtualstringtree suchen mit Child-Nodes
 
So, ich habe das ganze jetzt gelöst. Allerdings wirklich nur auf die Art und Weise, dass ich den Nodes jeweils ein Child zugefügt habe. Beim initialsieren (Expanding) des Nodes, führe ich erste ein...

Delphi-Quellcode:
vst.DeleteChildren(Node)
aus und füge erst dann die richtigen Nodes mit den Daten zu.

madas 16. Mär 2016 08:46

AW: Virtualstringtree suchen mit Child-Nodes
 
Zitat:

Zitat von Jens Hartmann (Beitrag 1332940)

Delphi-Quellcode:
//EditChange Suche
procedure TfReportClient.edtSearchChange(Sender: TObject);
begin
  vstKunden.BeginUpdate;
  vstKunden.IterateSubtree(nil, SpeedSearch, Pointer(edtSearch.Text), [], true);
  vstKunden.EndUpdate;
end;
Vieleicht fällt ja irgendetwas auf...

Gruß Jens

Also bei uns sieht der OnChange event vom Edit so aus:

Delphi-Quellcode:
procedure TFormTest.EditFilterSearchChange(Sender: TObject);
begin
  if (not (tsIterating in vstFilter.TreeStates)) then
    vstFilter.IterateSubtree(Node, vstFilterSearchCallback, nil);
end;
Sprich ohne
Delphi-Quellcode:
vstFilter.BeginUpdate
und
Delphi-Quellcode:
vstFilter.EndUpdate
.

CallBack schaut dann so aus:

Delphi-Quellcode:
procedure TFormTest.vstFilterSearchCallback(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean);
var
  nodeData: TFilterCustomItem;
begin
  if (Assigned(Node)) then
  begin
    nodeData := TFilterCustomItem(Sender.GetNodeData(Node)^);
    Sender.IsVisible[Node] := True;
    if (nodeData is TFilterFieldValue) then
    begin
      Sender.IsVisible[Node] :=
        (EditFilterSearch.Text = EmptyStr) or
        (AnsiContainsText(StringReplace(nodeData.CellText, ' ', '', [rfReplaceAll]), StringReplace(EditFilterSearch.Text, ' ', '', [rfReplaceAll])));
      if (Assigned(Node.Parent)) then
      begin
        ...
        // Parent wird dann hier auf Grund der sichtbaren Anzahl an Childs auch ein- bzw. ausgeblendet
        // Und falls vorhanden Parent.Parent auch
        ...
      end;
    end;
  end;
end;
Grüße madas


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz