AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TComponentList.Sort Problem

Ein Thema von berens · begonnen am 2. Okt 2006 · letzter Beitrag vom 2. Okt 2006
Antwort Antwort
berens

Registriert seit: 3. Sep 2004
431 Beiträge
 
Delphi 2010 Professional
 
#1

TComponentList.Sort Problem

  Alt 2. Okt 2006, 11:21
Diese Frage bezieht sich unter anderem auf: http://www.delphipraxis.net/internal...istsortcompare

Aufgabe: Ich möchte eine Liste (bzw. Objekte) anhand ihrer SortID sortieren. (Mehrere Objekte mit Align=alTop sollen von oben nach unten sortiert werden können. Mit SortID merke ich mir (intern), an welche Position die Objekte stehen.

Tfoo ist quasi ein Container der variabel viele TBar Objekte enthält (in der ComponentList).
Sobald ich nun foo.sort aufrufe, stimmt zwar Item1, jedoch ist Item2 immer = $2 --> Exception. Was auch immer das bedeutet.

Was tun?

Soweit ich das verstanden habe, besitzt TList intern eine Sortiermethode (Quicksort oder Bubblesort etc.) der jedoch die Sortierrichtung anhand meiner benutzerdefinierten Funktion vornimmt: Entsprechend des Results ist der Wert1 <, > oder = Wert2. Da ja die einzelnen Objekte der TComponentlist (denke ich mal) als Item1+2 übergeben werden, kann ich selbst definieren, welches Objekt < oder > ist, z.B. anhand meiner intSort, so wie ich es möchte. Bei der Fehlersuche kann ich auch immer die kompletten Objektdaten dieses Tbar einsehen (intSort etc.). Was ist denn nun mit diesem Item2 los? Schon bei dem ersten Vergleich spinnt es...

Delphi-Quellcode:

TMyListSortCompare = function (Item1, Item2: Pointer): Integer of object;

TBar= class(TMyPanel)
private
public
  ID: integer;
  intSort: integer;
  :
end;

Tfoo= class(TMyPanel)
private
  FCompareListItems:TMyListSortCompare;
  function CompareSortID(Item1, Item2: Pointer): Integer;
  :
public
  ComponentList: TComponentList;
  :
  constructor Create(_Owner: TComponent); override;
end;

constructor Tfoo.Create(_Owner: TComponent);
begin
  inherited Create(_Owner);
  :
  ComponentList := TComponentList.Create(True);
  FCompareListItems:= CompareSortID;
  :
end;


function Tfoo.CompareSortID(Item1, Item2: Pointer): Integer;
begin
  if not Assigned(Item1) or not Assigned(Item2) then begin
    Result := 0;
    Exit;
  end;
  if (TBar(Item1).intSort < TBar(Item2).intSort) then begin
    Result := -1; // i1 < i2
  end else begin
    if (TBar(Item1).intSort = TBar(Item2).intSort) then begin
      Result := 0; // i1 = i2
    end else begin
      Result := 1; // i1 > i2
    end;
  end;
end;

procedure Tfoo.Sort;
begin
  if ComponentList.Count > 1 then begin
    ComponentList.Sort(TListSortCompare(@FCompareListItems));
  end;
end;
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#2

Re: TComponentList.Sort Problem

  Alt 2. Okt 2006, 11:50
Hallo berens,

TList.Sort erwartet einen Zeiger auf eine einfache (nicht lokale) Funktion, keine Methode.

Versuche es einmal mit diesen Änderungen:

Delphi-Quellcode:
// TMyListSortCompare = function (Item1, Item2: Pointer): Integer of object; // nicht mehr benötigt

TBar= class(TMyPanel)
private
public
  ID: integer;
  intSort: integer;
  :
end;

Tfoo= class(TMyPanel)
private
// FCompareListItems:TMyListSortCompare; // ersetzt
  FCompareListItems:TListSortCompare; // neu
// function CompareSortID(Item1, Item2: Pointer): Integer; // nicht mehr benötigt
  :
public
  ComponentList: TComponentList;
  :
  constructor Create(_Owner: TComponent); override;
end;

// neu (ersetzt alte Methode)
function CompareSortID(Item1, Item2: Pointer): Integer;
begin
  if Assigned(Item1) and Assigned(Item2) then
    Result := TBar(Item1).intSort - TBar(Item2).intSort
  else
    Result := 0;
end;

constructor Tfoo.Create(_Owner: TComponent);
begin
  inherited Create(_Owner);
  :
  ComponentList := TComponentList.Create(True);
  FCompareListItems:= CompareSortID;
  :
end;

{ durch neue Routine ersetzt
function Tfoo.CompareSortID(Item1, Item2: Pointer): Integer;
begin
  if not Assigned(Item1) or not Assigned(Item2) then begin
    Result := 0;
    Exit;
  end;
  if (TBar(Item1).intSort < TBar(Item2).intSort) then begin
    Result := -1; // i1 < i2
  end else begin
    if (TBar(Item1).intSort = TBar(Item2).intSort) then begin
      Result := 0; // i1 = i2
    end else begin
      Result := 1; // i1 > i2
    end;
  end;
end;
}


procedure Tfoo.Sort;
begin
  if ComponentList.Count > 1 then begin
// ComponentList.Sort(TListSortCompare(@FCompareListItems)); // ersetzt
    ComponentList.Sort(FCompareListItems); // neu
  end;
end;
Gruß Hawkeye
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
431 Beiträge
 
Delphi 2010 Professional
 
#3

Re: TComponentList.Sort Problem

  Alt 2. Okt 2006, 11:58
Scheint zu klappen (muss das nachher mal testen, wenn intSort auch tatsächlich erstmal (unsortiert) vorliegt.

Wenn Du mir nun noch erklären kannst, warum in alle Wert die Sortierfunktion unbedingt nicht-lokal sein muss, könnte ich evtl. jemandem weis machen, ich hätte das Thema verstanden

Vielen Dank soweit!
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#4

Re: TComponentList.Sort Problem

  Alt 2. Okt 2006, 12:06
Zitat von Delphi-Hilfe:
Lokale Prozedur/Funktion '<Element>' wurde Prozedurenvariable zugewiesen

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, eine lokale Prozedur einer Prozedurvariable zuzuweisen oder sie als prozeduralen Parameter zu übergeben.

Dies ist nicht erlaubt, da die lokale Prozedur dann auch aufgerufen werden könnte, wenn die umgebende Prozedur nicht aktiv ist. Wenn die lokale Prozedur in diesem Fall versucht, auf Variablen der umgebenden Prozedur zuzugreifen, hat dies einen Programmabsturz zur Folge.
Es gibt sicher Fälle, in denen die oben genannten Bedingungen nicht zutreffen. Da der Compiler dies aber nicht sicher erkennen kann, weist er jeglichen Versuch zurück, eine lokale Routine zu verwenden.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:54 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