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/)
-   -   TTreeview sortieren (FMX) klappt nicht... (https://www.delphipraxis.net/193826-ttreeview-sortieren-fmx-klappt-nicht.html)

idontknow 13. Sep 2017 12:13

TTreeview sortieren (FMX) klappt nicht...
 
Merkwürdiges Problem, versuche gerade ein Treeview zu sortieren. Übergebe dazu mittels TTreeview.Sort einen Comparer, der die einzelnen Items anhand ihrer Tag-Eigenschaft sortieren soll. Habe zwei Comparer, einen für aufsteigende und einen für absteigende Sortierung. Wenn ich diesen Comparer übergebe:

Delphi-Quellcode:
function CompareAsc(Item1, Item2: TFmxObject): Integer;
begin
  Result := Item2.Tag - Item1.Tag;
end;
habe ich danach eine optisch leere Liste, in der aber immer noch Items vorhanden sind. Sie sind anklickbar, erscheinen aber ohne Text im Treeview.

So rum geht's:
Delphi-Quellcode:
function CompareDesc(Item1, Item2: TFmxObject): Integer;
begin
  Result := Item1.Tag - Item2.Tag;
end;
Habe Delphi 10.2

Was mache ich falsch? Mache ich überhaupt was falsch?

Schon mal vielen Dank fürs Angucken...

Hier mal das vollständige Programm:

Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
  FMX.TreeView;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

function CompareAsc(Item1, Item2: TFmxObject): Integer;
function CompareDesc(Item1, Item2: TFmxObject): Integer;

implementation

{$R *.fmx}

function CompareAsc(Item1, Item2: TFmxObject): Integer;
begin
  Result := Item2.Tag - Item1.Tag;
end;

function CompareDesc(Item1, Item2: TFmxObject): Integer;
begin
  Result := Item1.Tag - Item2.Tag;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  TreeViewItem: TTreeViewItem;
  i: Integer;
begin
  for i := 0 to 9 do
  begin
    TreeViewItem := TTreeViewItem.Create(TreeView1);
    TreeViewItem.Parent := TreeView1;
    TreeViewItem.Text := i.tostring;
    TreeViewItem.Tag := i;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  //TreeView1.BeginUpdate;
  TreeView1.Sort(CompareAsc);
  //TreeView1.EndUpdate;
  TreeView1.Repaint;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  //TreeView1.BeginUpdate;
  TreeView1.Sort(CompareDesc);
  //TreeView1.EndUpdate;
  TreeView1.Repaint;
end;

end.

idontknow 14. Sep 2017 12:40

AW: TTreeview sortieren (FMX) klappt nicht...
 
Okay, habe mittlerweile selber rausgefunden, das für die oberste Ebene des TTreeView die onCompare-Methode verwendet werden muss. Das funktioniert auch.

In meinem Programm, wo ich während der Realisierung über die Schwierigkeiten mit dem Sortieren des Treeviews gestolpert bin, habe ich jedoch Items, die wiederum SubItems haben. Habe jetzt folgenden Weg ausprobiert, der die Items der obersten Ebene einwandfrei sortiert. Die SubItems behalten jedoch ihre Sortierung bei, erst bei nochmaligem Aufruf meiner Methode "SortItems" werden dann auch die SubItems in der gewünschten Weise sortiert.

Und wieder stellt sich die Frage: Was mache ich falsch?

Hat jemand eine Idee?

Zur Erläuterung:
Nach Druck auf BtFillTreeView:
0
0
1
2
usw.
1
0
1
2
usw.
usw.

Nach dem ersten Aufruf von SortItems:
9
0
1
2
usw.
8
0
1
2
usw.
Nach einem weiteren Aufruf von SortItems:
9
9
8
7
usw.
8
9
8
7
usw.

Hier mein Testprogramm:
Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
  FMX.TreeView;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    BtFillTreeView: TButton;
    BtSortDesc: TButton;
    BtSortAsc: TButton;
    procedure BtFillTreeViewClick(Sender: TObject);
    procedure BtSortDescClick(Sender: TObject);
    procedure BtSortAscClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FlagSortDescending: Boolean;
    function TreeView1Compare(Item1, Item2: TTreeViewItem): Integer;
    function CompareItems(Item1, Item2: TFmxObject): Integer;
    procedure SortItems;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.BtFillTreeViewClick(Sender: TObject);
var
  TreeViewItem, TreeViewSubItem: TTreeViewItem;
  i, j: Integer;
begin
  for i := 0 to 9 do
  begin
    TreeViewItem := TTreeViewItem.Create(TreeView1);
    TreeViewItem.Parent := TreeView1;
    TreeViewItem.Text := i.ToString;
    TreeViewItem.Tag := i;
    for j := 0 to 9 do
    begin
      TreeViewSubItem := TTreeViewItem.Create(TreeView1);
      TreeViewSubItem.Parent := TreeViewItem;
      TreeViewSubItem.Text := j.ToString;
      TreeViewSubItem.Tag := j;
    end;
  end;
end;

procedure TForm1.BtSortDescClick(Sender: TObject);
begin
  FlagSortDescending := TRUE;
  SortItems; // das sortiert nur die "Ebene 0"...
  SortItems; // das sortiert dann auch die SubItems...
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TreeView1.OnCompare := TreeView1Compare;
end;

procedure TForm1.BtSortAscClick(Sender: TObject);
begin
  FlagSortDescending := FALSE;
  SortItems; // das sortiert nur die "Ebene 0"...
  SortItems; // das sortiert dann auch die SubItems...
end;

procedure TForm1.SortItems;
var
  i: Integer;
  TreeViewItem: TTreeViewItem;
begin
  TreeView1.Sorted := FALSE;
  TreeView1.Sorted := TRUE;

  for i := 0 to TreeView1.Count-1 do
  begin
    TreeViewItem := TreeView1.Items[i];
    TreeViewItem.Sort(CompareItems);
  end;

  TreeView1.Repaint;
end;

function TForm1.TreeView1Compare(Item1, Item2: TTreeViewItem): Integer;
begin
  Result := Item1.Tag - Item2.Tag;
  if FlagSortDescending then
    Result := -Result;
end;

function TForm1.CompareItems(Item1, Item2: TFmxObject): Integer;
begin
  Result := Item1.Tag - Item2.Tag;
  if FlagSortDescending then
    Result := -Result;
end;

end.

idontknow 14. Sep 2017 13:49

AW: TTreeview sortieren (FMX) klappt nicht...
 
Aaarrghh. Ich beantworte meine Frage selbst: Wenn der Inhalt von SortItems in Treeview1.BeginUpdate ... Treeview1.EndUpdate gekapselt wird, dann klappt es mit dem Sortieren auch beim ersten Aufruf... Hätte ich auch früher drauf kommen können...


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:57 Uhr.

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