![]() |
EListError, warum? ObjectList mit Daten füllen
Wie kann ich Daten in eine Stringliste korrekt übernehmen?
Ich will die Grid Komponente mal selber nachbauen. Ich habe folgenden Code:
Delphi-Quellcode:
Der Create Konstruktor sieht so aus:
procedure TCustomGrid.Paint;
var ACol,ARow,w,h,l,t,r,b: Integer; begin inherited Paint; for ARow:=0 to FRowsContainer.Count-1 do for ACol:=0 to TStringList(FRowsContainer.Items[ARow]).Count-1 do begin w := TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Width; h := TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Height; l := TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Left; t := TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Top; DrawRectangleClip(vscreen,l,t,l+w,t+h,ToColor(colBlack)); t := t + h; l := l + w; end; end;
Delphi-Quellcode:
Die relevanten Datenstrukturen sind wie folgt, definiert:
constructor TCustomGrid.Create(AOwner: TComponent);
begin inherited Create(AOwner); FRowsContainer := TObjectList.Create; FRowsContainer.Capacity := 10; FColsContainer := TStringList.Create; //wird gar nicht benötigt, kann aber zum Speichern zusätzlicher Infos verwendet werden FColsContainer.Capacity := 5; ClipRect := Rect(0,0,600,36); FHeight := ClipRect.Bottom - ClipRect.Top; FWidth := ClipRect.Right - ClipRect.Left; FRowHeight := 26; FColWidth := 60; CreateRows(9); CreateCols(5); FFixedCols := 0; FFixedRows := 0; end; procedure TCustomGrid.CreateCols(Count: Integer); begin SetCols(Count); end; procedure TCustomGrid.CreateRows(Count: Integer); begin SetRows(Count); end; procedure TCustomGrid.SetRows(AValue: Integer); //Zuerst SetRows, danach SetCols var ARow: Integer; AList: TStringList; begin if FRows=AValue then Exit; FRows:=AValue; for ARow := 0 to FRows-1 do begin AList := TStringList.Create; AList.Capacity := 5; FRowsContainer.Add(AList); end; end; procedure TCustomGrid.SetCols(AValue: Integer); //Passiert am Anfang vor Benutzung des Grids var ACol,ARow: Integer; begin if FCols=AValue then Exit; FCols:=AValue; for ARow := 0 to FRowsContainer.Count -1 do begin for ACol := 0 to FCols-1 do TStringList(FRowsContainer.Items[ARow]).AddObject(' ', TGridColumn.Create(self)); TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Width := FColWidth; TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Height := FRowHeight; end; end; Das Grid enhält in einer Stringliste die Spaltenstrings, in Objects eine TGridColumn mit allen Daten. Eine TObjectList nimmt je Zeile dann eine TStringList auf, deren Strings die Spalten bilden, sofern die Spalteninhalte Strings sind oder bei Integer oder Double Werten die String Repräsentation dieser Werte.
Delphi-Quellcode:
{ TGridColDimension }
TGridColDimension = record Height: Integer; Width: Integer; end; TGridDataItem = record Dimension: TGridColDimension; Field: TObject; //Für ein TField Objekt //Fieldnum: Integer; case Longword of 0: (BinData : TObject); //Binärdaten aufnehmen 1: (Contents: Longword); 2: (Int32Val: Integer); 3: (FloatVal: Double); 4: (Int16Val: smallint); end; { TGridGenericItem } TGridGenericItem = class(TObject) private FGridData: TGridDataItem; function GetGridData: TGridDataItem; procedure SetGridData(AValue: TGridDataItem); public constructor Create; constructor Create(AData: TObject); destructor Destroy; override; property GridData: TGridDataItem read GetGridData write SetGridData; end; { TGridColumn } TGridColumn = class(TBaseControl) private FItem: TGridGenericItem; FLeft: Integer; FTop: Integer; function GetContent: TGridGenericItem; function GetWidth: Integer; function GetHeight: Integer; procedure SetContent(AValue: TGridGenericItem); procedure SetLeft(AValue: Integer); procedure SetTop(AValue: Integer); procedure SetWidth(AValue: Integer); procedure SetHeight(AValue: Integer); public constructor Create(AOwner: TComponent); destructor Destroy; override; procedure Paint; override; property Content: TGridGenericItem read GetContent write SetContent; property Left: Integer read FLeft write SetLeft; property Top: Integer read FTop write SetTop; property Width: Integer read GetWidth write SetWidth; property Height: Integer read GetHeight write SetHeight; end; { TCustomGrid } TCustomGrid = class(TBaseControl) private FCols: Integer; FFixedCols: Integer; FFixedRows: Integer; FRows: Integer; FColsContainer: TStrings; //in Objects[Index] -> TGridGenericItem FRowsContainer: TObjectList; FRowHeight: Integer; FColWidth: Integer; function GetCells(X, Y: Integer): String; function GetColHeights(Index: Integer): Integer; function GetColWidths(Index: Integer): Integer; function GetItems(X,Y: Integer): TGridColumn; procedure SetCells(X, Y: Integer; AValue: String); procedure SetColHeights(Index: Integer; AValue: Integer); procedure SetCols(AValue: Integer); procedure SetColWidth(AValue: Integer); procedure SetColWidths(Index: Integer; AValue: Integer); procedure SetFixedCols(AValue: Integer); procedure SetFixedRows(AValue: Integer); procedure SetItems(X,Y: Integer; AValue: TGridColumn); procedure SetRowHeight(AValue: Integer); procedure SetRows(AValue: Integer); public constructor Create(AOwner: TComponent); destructor Destroy; override; procedure AddRow; procedure CreateCols(Count: Integer); procedure CreateRows(Count: Integer); procedure Paint; override; property Cells[X,Y: Integer]: String read GetCells write SetCells; property Cols: Integer read FCols write SetCols; //Anzahl Spalten. Count of columns. property Rows: Integer read FRows write SetRows; //Anzahl Zeilen. Count of rows. property FixedCols: Integer read FFixedCols write SetFixedCols; //for column title property FixedRows: Integer read FFixedRows write SetFixedRows; //for row title property Items[X,Y: Integer]: TGridColumn read GetItems write SetItems; //Inhalte der Zellen, in cells immer als String, hier aber die realen Werte property RowHeight: Integer read FRowHeight write SetRowHeight; property ColWidth: Integer read FColWidth write SetColWidth; property ColHeights[Index: Integer]: Integer read GetColHeights write SetColHeights; //Rückgabetyp noch überlegen property ColWidths[Index: Integer]: Integer read GetColWidths write SetColWidths; end; Was mache ich mit der Stringliste falsch? Ich bekommen einen EListError, der mir als Meldung die letzte Zeile der Objektliste FRowsContainer anzeigt. Warum. Wie kann ich dieses Problem elegant umgehen? |
AW: EListError, warum? ObjectList mit Daten füllen
Habe jetzt nicht nach deinen fehler gesucht aber könnte man das nicht auch so schreiben?
Delphi-Quellcode:
t := t + h;
l := l + w;
Delphi-Quellcode:
inc(t, h);
inc(l, w); |
AW: EListError, warum? ObjectList mit Daten füllen
Warum überhaupt dieses Hochzählen, wo die Werte doch im nächsten Durchlauf wieder gesetzt werden?
|
AW: EListError, warum? ObjectList mit Daten füllen
Zitat:
EDIT: Eventuell so wenn t und l global definiert sind.
Delphi-Quellcode:
l := l + TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Left;
t := t + TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Top; inc(t, h); inc(l, w); |
AW: EListError, warum? ObjectList mit Daten füllen
Moin,
vielleicht solltest du ein kleines Test-Programm posten, dann kann man das auch leichter testen. Was mir komisch vorkommt, so beim ersten drüber schauen (neben dem von Uwe Raabe), dass du in den Methoden SetRows und SetCols die Liste von 0 bis zur gewünschten neuen Zeilenzahl (um mal bei SetRows zu bleiben) füllst. Wird das aber ein zweites mal aufgerufen leerst du die derzeitige Liste nicht, bzw. füllst nur noch den neuen Anteil auf. Als zweites würde ich in der geschachtelten Forschleife TStringList(FRowsContainer.Items[ARow]) zwischenspeichern ... das macht das Ganze etwas lesbarer meiner Meinung nach. Außerdem kannst du dann auch leicht in Delphi beim Debuggen in die StingrListe rein schauen, was auch hilfreich sein kann. Als drittes fehlt in SetCols in der inneren For-Schleife das begin-end, wodurch nur die eine Zeile ausgeführt wird. Auch hier wieder mein Appell: Macht auch für einzeilige Sachen bei bedingungen (if) oder schleifen (for, while, ...) IMMER begin-end. Du bist nicht der erste der solch einen Fehler hat. Das klang jetzt negativer als es gemeint war. Bitte nicht negativ lesen! 😅 Ich hoffe das hilft etwas. Liebe Grüße Incocnito |
AW: EListError, warum? ObjectList mit Daten füllen
Zitat:
Aber warum bekomme ich den EListError? Und wie kann ich den bei solchen Listen ein für allemal umgehen, den hatte ich schon mehrfach mit Listen? |
AW: EListError, warum? ObjectList mit Daten füllen
Zitat:
|
AW: EListError, warum? ObjectList mit Daten füllen
Zitat:
Delphi-Quellcode:
Besser wäre aber das ganze wie oben schon erwähnt mit einer lokalen Variable zu lösen:
for ACol := 0 to FCols-1 do TStringList(FRowsContainer.Items[ARow]).AddObject(' ', TGridColumn.Create(self));
TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Width := FColWidth; TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Height := FRowHeight;
Delphi-Quellcode:
for ACol := 0 to FCols-1 do begin
var gridColumn := TGridColumn.Create(self); gridColumn.Width := FColWidth; gridColumn.Height := FRowHeight; TStringList(FRowsContainer.Items[ARow]).AddObject(' ', gridColumn); end; |
AW: EListError, warum? ObjectList mit Daten füllen
Zitat:
|
AW: EListError, warum? ObjectList mit Daten füllen
Zitat:
Die letzte im Eingangspost oder die letzte in welcher der Prozeduren? Zitat:
Ein Fehler, der durch nicht ganz korrekte Zählweise entstehen könnte oder die Variante, dass da irgendwo eine Dublette in 'ner Stringliste eingefügt wird? Bei Zählfehlern könnte man ggfls. hier im Forum behilflich sein, wenn die exakte Fehlerzeile mal bekanntgegeben wird. Einen potentiellen Dublettenfehler können wir so ohne weiteres nicht erkennen. Weder kennen wir die zu verarbeitenden Daten noch wissen wir, ob die Stringlisten sortiert sein könnten und das Einfügen von Dubletten eventuell nicht möglich ist. Die dritte Variante könnte eintreten, wenn bei einer Liste, deren
Delphi-Quellcode:
ist, das sechste Element eingefügt wird.
AList.Capacity := 5;
Hier könnte ggfls. ein
Delphi-Quellcode:
(oder ein beliebiger anderer Wert > 5?) Fehlerursache sein.
SetCols(6);
Oder ich könnte mit meinen Mutmaßungen auch vollständig daneben liegen ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22: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 by Thomas Breitkreuz