Einzelnen Beitrag anzeigen

Peter666

Registriert seit: 11. Aug 2007
357 Beiträge
 
#1

Treeview in Firemonkey XE2

  Alt 25. Mai 2013, 18:40
Hi,

derzeit muss ich notgedrungen Firemonkey für ein Projekt nutzen und ich könnte mir die Haare einzeln ausreißen. Mir ist im speziellen Fall des Treeviews die unterirdische Performance beim Aufklappen des Baumes aufgefallen. Sobald man mehrere TreeviewItem's mit Unterobjekten hat passiert das.
Sieht man mal davon ab das knapp 1800 Einträge in einer Treeview eigentlich nicht das System auch nur im Ansatz belasten sollten, so dauert das Öffnen einer Node knapp 30 Sekunden und der Ramverbrauch stieg auf knapp 1gb an. Mein Baum hat 4 Unterzweige mit jeweils ein paar Dutzend Items, das konnte selbst ein oller Celeron unter 98 innerhalb von wenigen Nanosekunden.
In XE4 ist das Problem nicht mehr vorhanden, dazu komme ich aber noch später in dem Post

Da ja der Quellcode in der Professional Version von Delphi mitgeliefert ist, habe ich mir also die FMX.Treeview.pas in mein Projektpfad kopiert und den Verweis auf die Include Datei mit den Compileroptionen ausgeklammert, weil die wird da eh nicht drin benutzt. Der Grund für die unterirdische Performance: procedure TTreeViewItem.SetIsExpanded(const Value: Boolean);

Delphi-Quellcode:
procedure TTreeViewItem.SetIsExpanded(const Value: Boolean);
var
  i: Integer;
  Item: TTreeViewItem;
begin
  if FIsExpanded <> Value then
  begin
    FIsExpanded := Value;

    if FContent.ChildrenCount > 0 then
      for i := FContent.ChildrenCount - 1 downto 0 do
      begin
        Item := nil;
        if FContent.Children[i] is TTreeViewItem then
          Item := TTreeViewItem(FContent.Children[i]);

        if Item <> nil then
          Item.IsExpanded := True;
      end;

    if (FButton <> nil) and not(csLoading in ComponentState) then
    begin
      FButton.Visible := Count > 0;
      if FButton.Visible then
        FButton.StartTriggerAnimation(Self, 'IsExpanded');
    end;

     if (TreeView <> nil) then
      TreeView.Realign;
  end;
end;
Sieht man mal davon ab, dass es ein Unding ist bei einem Treeview automatisch alle Untersektionen aufzuklappen, so ist das nicht der Grund für die quälend langsame Verarbeitung.
Beim weiteren Debuggen ist mir eine Zeile aufgefallen die der Übeltäter ist. Ich denke mal diejenigen die das Post hier lesen, sehen das auch sofort...
Richtig TreeView.Realign wird automatisch bei jedem Unterelement ausgeführt und das komplette Treeview veranlasst sich selbst neu auszurichten und neu zu zeichnen.
Welcher Depp macht so etwas? Ich nutze XE4 nicht wirklich, da ich auch nicht den Quellcode von dort habe rate ich mal das das in der Form auch so hinterlegt ist und man das Autoexpand schlichtweg deaktiviert hat.

Der Grund für mein Post ist jedoch ein anderer. Ich fürchte das mir sowas bei Listboxen mit Sicherheit auch noch entgegenschlägt und ebenso bei anderen Komponenten. Wie aktualisiere ich am besten die Originalquellen so dass man nicht ständig den halben Firemonkeycode von Projekt zu Projekt mitziehen muss?

Peter

Geändert von Peter666 (25. Mai 2013 um 18:43 Uhr)
  Mit Zitat antworten Zitat