Hi,
grundsätzlich halte ich TCollection für den richtigen Weg. Nun progge ich nicht jeden Tag Kompos mit TCollection und kann somit meine Hand nicht dafür ins Feuer legen, dass das der perfekte Weg ist. Aber so habe ich es gemacht. Günstig ist es auf jeden Fall ein TListItem-element als Hilfe wie es funst zu benutzen.
als erstes benötigst du ein Control, welches deine Elemente hält. Das hast du ja schon; deine Kalenderkompo als TCustomGrid.
Diese benötigt jetzt eine property Items. das sieht dann etwa so aus:
Delphi-Quellcode:
TMyControl = class(TCustomControl)
private
procedure SetMyItems(const Value: TLCItems);
published
property Items: TMyItems read FMyItems write SetMyItems;
end;
procedure TLineControl.SetMyItems(const Value: TMyItems);
begin
FMyItems.Assign(Value);
end;
Mein TCollection-Object sieht dann so aus
Delphi-Quellcode:
TMyItems = class(TCollection)
private
FLineControl: TMyControl;
function GetItem(Index: Integer): TMyItem;
procedure SetItem(Index: Integer; Value: TMyItem);
protected
function GetOwner: TPersistent; override;
procedure Update(Item: TCollectionItem); override;
public
constructor Create(AControl: TMyControl);
function Add: TMyItem;
procedure Refresh;
property Items[Index: Integer]: TMyItem read GetItem write SetItem;
default;
end;
// hier ein Bspiel für SetItem
procedure TMyItems.SetItem(Index: Integer; Value: TMyItem);
begin
inherited SetItem(Index, Value);
end;
Hier sind zwei Sachen entscheidend, im Constructor wird das Parent-Control aufgerufen. Dies erfolgt, um denren Zeichenroutinen nach Änderung der Item aufrufen zu können. Im weiteren händelt die Collektion die grundlegenden Methoden für die Erstellung und den Zugriff auf die Item.
Die Item sehen dann so aus:
Delphi-Quellcode:
TMyItem = class(TCollectionItem)
private
FParent: TLCItems;
FRect : TRect;
FCaption: String;
procedure SetCaption(const Value: String);
protected
public
constructor Create(Collection: TCollection); override;
procedure Update; virtual;
procedure Assign(Source: TPersistent); override;
property Data : Pointer read FData write FData;
published
property Caption : String read FCaption write SetCaption;
end;
Denk an die Forward-Deklaration für TMyItems und TMyControl.
gezeichnet wird im TMyControl. Dazu besitzt bei mir TMyControl eine Methode
procedure DrawItem(Item: TLCItem; ACanvas: TCanvas; var R: TRect); virtual;
Hierbei ist Canvas der Canvas von TMyControl. Es wird direkt in den Canvas gezeichnet. Ob das so die ideale Methode ist mag ich nicht zu sagen. Vielleicht hast du oder ein anderer eine bessere Idee.
gruß oki