Einzelnen Beitrag anzeigen

delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
266 Beiträge
 
Delphi 10.3 Rio
 
#1

EListError, warum? ObjectList mit Daten füllen

  Alt 20. Mai 2022, 14:46
Wie kann ich Daten in eine Stringliste korrekt übernehmen?

Ich will die Grid Komponente mal selber nachbauen.

Ich habe folgenden Code:

Delphi-Quellcode:
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;
Der Create Konstruktor sieht so aus:

Delphi-Quellcode:
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;
Die relevanten Datenstrukturen sind wie folgt, definiert:

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?

Geändert von delphifan2004 (20. Mai 2022 um 14:49 Uhr)
  Mit Zitat antworten Zitat