Wie eine TCollection-Eigenschaft einer Unterkomponente, z. die Columns-Eigenschaft eines eingebetteten TDBGrid
Ich habe versucht, mich auf einen MCVE-Code zu beschränken, den mir der Autor eines anderen q geschickt hat, um ein Problem mit einer benutzerdefinierten Komponente zu veranschaulichen.
Die Komponente ist einfach ein TPanel-Nachkomme, der ein eingebettetes TDBGrid enthält. Meine Version der Quelle und ein Testprojekt finden Sie weiter unten.
Das Problem ist, dass, wenn das eingebettete DBGrid mit persistenten Spalten erstellt wurde, beim erneuten Öffnen seines Testprojekts in der IDE eine Ausnahme ausgelöst wird
Fehler beim LesenTColumn.Grid.Expanded
. EigentumGrid
ist nicht vorhanden
Ausführen desStream
ie @ -Methode des Testprojekts zeigt, wie dieses Problem auftritt:
Zum Vergleich habe ich auch ein normales TDBGrid, DBGrid1, in meinem Formular. Während die Spalten dieses DBGrid1 als @ gestreamt werd
Columns = <
item
Expanded = False
FieldName = 'ID'
Visible = True
end
[...]
die Spalten des eingebetteten Gitters werden wie folgt gestreamt
Grid.Columns = <
item
Grid.Expanded = False
Grid.FieldName = 'ID'
Grid.Visible = True
end
[...]
Es ist offensichtlich dasGrid
Präfix vonGrid.Expanded
und die anderen Spalteneigenschaften, die das Problem verursachen.
Ich stelle mir vor, dass das Problem damit zusammenhängt, dass DBGridColumns ein Nachkomme von TCollection ist und das eingebettete Raster nicht das Objekt der obersten Ebene in DFM ist.
Meine Frage ist: Wie soll der Code vonTMyPanel
so geändert werden, dass die Spalten des Rasters korrekt gestreamt werden?
Komponentenquelle:
unit MAGridu;
interface
uses
Windows, SysUtils, Classes, Controls, ExtCtrls, DBGrids;
type
TMyPanel = class(TPanel)
private
FGrid : TDBGrid;
public
constructor Create(AOwner : TComponent); override;
published
property Grid : TDBGrid read FGrid;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard', [TMyPanel]);
end;
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FGrid := TDBGrid.Create(Self);
FGrid.SetSubcomponent(True);
FGrid.Parent := Self;
end;
end.
Test Projektquelle:
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
CDS1: TClientDataSet;
DataSource1: TDataSource;
MyPanel1: TMyPanel;
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure Stream;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Stream;
end;
procedure TForm1.Stream;
// This method is included as an easy way of getting at the contents of the project's
// DFM. It saves the form to a stream, and loads it into a memo on the form.
var
SS : TStringStream;
MS : TMemoryStream;
Writer : TWriter;
begin
SS := TStringStream.Create('');
MS := TMemoryStream.Create;
Writer := TWriter.Create(MS, 4096);
try
Writer.Root := Self;
Writer.WriteSignature;
Writer.WriteComponent(Self);
Writer.FlushBuffer;
MS.Position := 0;
ObjectBinaryToText(MS, SS);
Memo1.Lines.Text := SS.DataString;
finally
Writer.Free;
MS.Free;
SS.Free;
end;
end;
end.
procedure TForm1.FormCreate(Sender: TObject);
var
Field : TField;
begin
Field := TIntegerField.Create(Self);
Field.FieldName := 'ID';
Field.FieldKind := fkData;
Field.DataSet := CDS1;
Field := TStringField.Create(Self);
Field.FieldName := 'Name';
Field.Size := 20;
Field.FieldKind := fkData;
Field.DataSet := CDS1;
CDS1.CreateDataSet;
CDS1.InsertRecord([1, 'One']);
end;
end.