AGB  ·  Datenschutz  ·  Impressum  







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

TCollection, TCollectionItem

Ein Thema von uwewo · begonnen am 6. Okt 2006 · letzter Beitrag vom 6. Nov 2006
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
uwewo

Registriert seit: 14. Jul 2004
Ort: Karlsruhe
479 Beiträge
 
Delphi 2006 Professional
 
#1

TCollection, TCollectionItem

  Alt 6. Okt 2006, 07:14
Hallo,

ich habe am Anfang des Jahres angefangen meine erste Komponente zu programmieren, da ich jetzt wieder mehr Zeit habe möchte ich gerne daran weiterarbeiten.

Es soll eine Kalenderkomponente werden abgeleitet von TCustomGrid. Auf diesem Grid soll man Objekte abgeleitet von TGraphicControl ablegen können, die die Einträge im Kalender verwalten.
Siehe Screenshot.

Um diese Objekte zu verwalten müßte ich meiner Komponente nun die Klasse TCollection hinzufügen, glaube ich jedenfalls.

So und nun zu meinem Verständnisproblem:

1. Wo muß ich die Klasse TCollection erstellen, wahrscheinlich beim erstellen meines Grids, oder?
2. Müssen die TCollectionItems von meinen Einträgen oder die Einträge von TCollectionItems erstellt werden?

Falls jemand etwas direkt in meinen Source schreiben will, kann ich ihn auch noch anhängen.

Habe mir schon sehr viele Quellcodes angeschaut, da aber in den meisten alle möglichen Klassen verschachtelt sind habe ich die Logik einfach noch nicht verstanden.

Hoffe es wahr einigermaßen verständlich was ich von Euch möchte.

Danke im voraus

Uwe
Miniaturansicht angehängter Grafiken
screenshot_364.jpg  
Uwe
  Mit Zitat antworten Zitat
uwewo

Registriert seit: 14. Jul 2004
Ort: Karlsruhe
479 Beiträge
 
Delphi 2006 Professional
 
#2

Re: TCollection, TCollectionItem

  Alt 9. Okt 2006, 06:16
Hi,

Ok, vielleicht war meine Frage zu kompliziert gestellt, deshalb versuche ich es nocheinmal.

Ich habe mir ein Grid erstellt, in dem ich das Datum in Spalten und die Uhrzeit oder frei definierbare Texte, in Zeilen anzeigen lassen kann. Auf dieses Grid, möchte ich DateItems als Einträge im Kalender anzeigen lassen. Siehe Screenshot erstes Posting.

Delphi-Quellcode:
TDateLine = TCustomGrid
TDateItem = TGraphicControl
Wie kann ich am besten die Einträge(TDateItem) verwalten, in TCollection? Oder gibt es bessere Methoden?
Wie müßte ich das ganze dann aufbauen, wo was deklarieren. Für die Zukunft würde ich gerne auch die Einträge in einer DB speichern können.

Hoffe es gibt doch jemand da draußen, der mir eine kleine Hilfestellung geben kann.

Danke
Uwe
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#3

Re: TCollection, TCollectionItem

  Alt 9. Okt 2006, 07:37
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
  Mit Zitat antworten Zitat
uwewo

Registriert seit: 14. Jul 2004
Ort: Karlsruhe
479 Beiträge
 
Delphi 2006 Professional
 
#4

Re: TCollection, TCollectionItem

  Alt 9. Okt 2006, 14:18
Erstmal Vielen Dank oki,

werde mir das ganze mal durch den Kopf gehen lassen und natürlich auch ausprobieren.

Danke, Danke!
Uwe
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#5

Re: TCollection, TCollectionItem

  Alt 11. Okt 2006, 15:23
Hi uwewo,

habe deinen code bekommen und schon mal rein geschaut. Ich glaube hier muß man eine grundsätzliche Entscheidung für die Vorgehensweise finden. entweder man benutzt TCollections oder eigene Listen in denen die Elemente gehalten werden. Hierbei ist es dann aber so, dass bei TCollection der weg an TColletionItem nicht vorbei geht. Hier ist dann nichts mit TCustomControl!!! Ein Trick ist es dann vielleicht, wenn mann das CustomControl (hier TDateItem) in einer neuen Eigenschaft "Controldata" versteckt. Ob der Aufwand damit aber nicht zu hoch wird ist hier die Frage.

Alternativ könnte man dann über Object-Listen arbeiten, in denen dann die DateItem gesammelt werden.
Ob das weniger Aufwand ist? Keine Ahnung. Egal über welchen Weg du gehst, helfen kann ich dir sicher. Das es der effektivste Weg ist kann ich aber nicht garantieren. Die Thematik eines anständigen Item-Editors zu designtime hab ich persönlich jedoch noch nicht umgesetzt (war mir für eigene Kompos zu viel Aufwand).

o.k. sag welche Methode du möchtest und es kann los gehen.

Gruß oki

P.S. Nach dem ich meinen eigenen Beitrag noch mal gelesen habe tendiere ich zu den TCollection.
  Mit Zitat antworten Zitat
uwewo

Registriert seit: 14. Jul 2004
Ort: Karlsruhe
479 Beiträge
 
Delphi 2006 Professional
 
#6

Re: TCollection, TCollectionItem

  Alt 12. Okt 2006, 06:20
Hallo oki,

danke das Du es dir angeschaut hast, TCollection denke ich wird der richtige Weg sein.

Wäre es möglich TCollection und TCollectionItem zu erstellen, und nur die Eigenschaften von TDateItem
in TCollectionItem zu lesen und zu schreiben?

Damit die eigentliche Routine zum zeichnen, sowie die Eigenschaften von TDateItem in der Klasse TDateItem bleiben?
Uwe
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#7

Re: TCollection, TCollectionItem

  Alt 13. Okt 2006, 07:09
Hi,

Zitat von uwewo:
Wäre es möglich TCollection und TCollectionItem zu erstellen, und nur die Eigenschaften von TDateItem
in TCollectionItem zu lesen und zu schreiben?
genau das ist der springende Punkt bei der Sache mit TcollectionItem. Willst Du deine Einträge ausschließlich von TCollectionItem ableiten, so müssen diese im Parent per "Hand" gezeichnet werden (auf den vorhandenen Canvas).

Das ist wohl so üblich. Die nächste Frage ist jetzt aber ob man nicht auch einen anderen Weg gehen kann. Wenn es sinn macht die Einträge als TWincontrol auf dem Parent darzustellen, dann kann man natürlich dem TCollectionItem auch eine Eigenschaft vom Typ TControlItem(TCustomControl) verpassen. Deises dann auf das Parent geklebt, und mann spart sich die vielen aufwendigen Zeichenroutinen. Bedenke, das geder Eintrag gezeichnet werden muß, und das für mehrere Zustände (selektiert, nicht selektiert etc.) Ich glaube das grundlegende Plroblem wird wohl eher die Performance sein. Nun gut, zur not können wir es ja einfach ausprobieren.

Ich hab mal angefangen deinen Code zu überarbeiten und werde ihn sicher heute Versandfertig haben. Dann können wir die ersten Sachen vielleicht heute testen und die ersten Ergebnisse posten.

Gruß oki
  Mit Zitat antworten Zitat
uwewo

Registriert seit: 14. Jul 2004
Ort: Karlsruhe
479 Beiträge
 
Delphi 2006 Professional
 
#8

Re: TCollection, TCollectionItem

  Alt 13. Okt 2006, 07:53
Hört sich ja gut an. Wenn ich schon etwas vorbereiten kann das Dir hilft, sag Bescheid.

Das Zeichnen der Items auf dem Grid funktioniert ja soweit schon, ich weiß natürlich nicht ob Du es ausprobiert hast.
Uwe
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#9

Re: TCollection, TCollectionItem

  Alt 13. Okt 2006, 07:58
Hi,

tschuldige, aber ich bin in 1 Minute offline. Nein hab ich nicht getestet, mach ich noch. Bin nur gerade beim umschreiben.

bis später Gruß oki
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#10

Re: TCollection, TCollectionItem

  Alt 13. Okt 2006, 14:00
Hi uwewo,

so, jetzt mal zum Ansatz und Aufbau deiner neuen Kompo TDateLine.

TDateLine ist vom Typ TCustomGrid und damit ein Nachfahre von TComponent.
TDateLine hält einen Member TDateItems vom Typ TCollection.
TDateItems hält die Einträge TDateItem vom Typ TCollectionItem.

Da du deine Einträge gerne als TCustomControls haben möchtest, hält jetzt genau jedes TDateItem ein TControlDateItem vom Typ TCustomControl. Somit verknüpfen wir ursächlich jedes Control mit einem Listeneintrag im DateLine.

das sieht im Objectaufbau etwa so aus:
Delphi-Quellcode:
  // Forward
  TDateLine = class;
  TDateItems = class;

 TControlDateItem = class(TCustomControl)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
    procedure Paint; override;
  public
    { Public-Deklarationen }
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
  published
    { Published-Deklarationen }
 end;
 
  TDateItem = class(TCollectionItem)
  private
    FParent : TDateItems;
    FControlDateItem : TControlDateItem;
  protected
  public
    constructor Create(Collection: TCollection); override;
  end;

  TDateItems = class(TCollection)
  private
    FDateLine: TDateLine;
    function GetItem(Index: Integer): TDateItem;
    procedure SetItem(Index: Integer; Value: TDateItem);
  protected
    function GetOwner: TPersistent; override;
    procedure Update(Item: TDateItem); reintroduce;
  public
    constructor Create(DateLine: TDateLine);
    function Add: TDateItem;
    procedure Refresh;
    property Items[Index: Integer]: TDateItem read GetItem write SetItem;
    default;
  end;

TDateLine = class(TCustomGrid)
  private
    { Private-Deklarationen }
    FDateItems : TDateItems;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
      property Items: TDateItems read FDateItems write SetDateItems;
  end;
Ich habe hier die spezifischen Eigenschaften weg gelassen.

Ein neues Item im DateLine kann jetzt wie gewohn erschaffen werden.

Delphi-Quellcode:
var Item : TDateItem;
begin
  Item := MyLineControl.Items.Add;
Im Constructor von TDateItem geschieht jetzt folgendes:
Delphi-Quellcode:
constructor TDateItem.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FParent := TDateItems(Collection);
  FControlDateItem := TControlDateItem.Create((Collection as TDateItems).FDateLine);
end;
Es wird automatisch ein zugehöriges TControlDateItem kreiert. Achte aber darauf, dass der Owner hier nicht self (das Item) sonder TDateLine, also die Kompo ist. Dort soll das Control ja auch platziert werden.

Jetzt ist mir aufgefallen, dass du ne menge obstruser Eigenschaften definierst. Bsp.
Delphi-Quellcode:
 TControlDateItem = class(TCustomControl)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
  published
    { Published-Deklarationen }
   property Height;// default 65;
   property Width;// default 65;
   property ColLeft : Integer read FColLeft write FColLeft;
   property RowTop : Integer read FRowTop write FRowTop;
   property ColCount : Integer read FColCount write FColCount;
   property RowCount : Integer read FRowCount write FRowCount;
   property Shape : TItemForm read FShape write SetShape;
   property Brush : TBrush read FBrush write SetBrush;
   property Pen : TPen read FPen write SetPen;
   property Text : String read FText write SetText;
   property Font : TFont read FFont write SetFont;
 end;
Ich unterstell mal, das bei entsprechenden Kalendereinträgen niemand die Breite und Höhe in Pixeln eingibt. Damit sind diese Werte für diese Anwendung wenn schon nicht im Public, so doch im published-Teil sehr fraglich.

Hie veröffentlicht mann eher die Eigenschaften:
Delphi-Quellcode:
  property StartDate : TDateTime read FStartDate write SetStartDate;
  property EndDate : TDateTime read FEndDate write SetEndDate;
die entsprechenden Set-Methoden berechnen und setzen dann die richtigen Werte für Höhe, Breite und Position im DateLine. Bei einer Aktualisierung brauchen dann auch nur noch diese Methoden aufgerufen werden und das Control passt sich automatisch den neuen Einstellungen von DateLine an.

Bu, jetzt hab ich krumme Finger, bis später

oki

P.S. in meinem Code per PM entferne die Auskommentierungen vom 11.10 in TDateItems!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


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 14:29 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