Hi,
irgendwie scheint es, ohne Nahe zu treten zu wohlen, das du mit
get und
set ganz allgemein
ein Problem hast.
Beispiel:
Zitat:
Wenn ich also die published Property "Labeled" im Objektinspektor von false (default-Einstellung) auf true setze, dann zeigt er das Label auch an (DesignTime) aber beim Starten (RunTime) kommt dann eine Fehlermeldung.
Davon ist aber im Code nichts zu sehen:
Delphi-Quellcode:
...
property Labeled: boolean read GetLabeled write SetLabeled;
...
sollte dann wohl so aussehen:
Delphi-Quellcode:
...
property Labeled: boolean read GetLabeled write SetLabeled default false;
...
Weiter geht es mit GetLabeled, statt so:
Delphi-Quellcode:
function TLabTrackBar.GetLabeled;
begin
result := FbLabeled;
end;
lieber so:
Delphi-Quellcode:
function TLabTrackBar.GetLabeled;
begin
if Assigned(FLblTrckBar) then result := FbLabeled
else Result := false;
end;
Und bei SetLabeled, statt so:
Delphi-Quellcode:
procedure TLabTrackBar.SetLabeled(bWert: Boolean);
begin
case bWert of
true: begin
FLblTrckBar := CreateLabel(floattostr(FtrckBar.Position*FScaleFactor) + FsLabelAdd);
LblAnpassung(FLblTrckBar);
end;
false: FreeandNil(FLblTrckBar);
end;
FbLabeled := bWert;
end;
doch wohl eher so:
Delphi-Quellcode:
procedure TLabTrackBar.SetLabeled(bWert: Boolean);
begin
if FbLabeled <> bWert then
begin
FbLabeled := bWert;
if FbLabeled then
begin
FLblTrckBar := CreateLabel(floattostr(FtrckBar.Position*FScaleFactor) + FsLabelAdd);
LblAnpassung(FLblTrckBar);
end
else FLblTrckBar.Free;
end;
end;
Nun zu Design- und Runtime:
Ich persönlich nutze den
kleinen Unterschied ganz gerne, wenn ich in einer Komponentensammlung
intern wiederholt von gleichen Komponenten ableite, aber trotzdem einzelne Komponenten nutzen/veröffentlichen
möchte.
Auch hierzu ein Beispiel:
Benötigt wird die Möglichkeit ein TPanel sichtbar/unsichtbar machen und darauf reagieren zu können.
Daraus folgt:
Delphi-Quellcode:
...
TVisibleChangeEvent = procedure (Value : Boolean) of object;
...
TCustomPanel = class (TPanel)
private
FOnChangeVisible: TVisibleChangeEvent;
function GetVisible: Boolean;
procedure SetVisible(Value: Boolean);
public
property OnChangeVisible: TVisibleChangeEvent read FOnChangeVisible write
FOnChangeVisible;
property Visible: Boolean read GetVisible write SetVisible;
end;
...
implementation
...
function TCustomPanel.GetVisible: Boolean;
begin
Result := TControl(Self).Visible;
end;
procedure TCustomPanel.SetVisible(Value: Boolean);
begin
TControl(Self).Visible := Value;
if Assigned(FOnChangeVisible) then FOnChangeVisible(Value);
end;
...
Da ich innerhalb der
Unit noch andere Objekte davon ableiten möchte, sind die
properties nur
public.
Das Sichtbar machen für den User und damit für den Objektinspector erfolgt gesondert,
und zwar in der Art, das ich ein weiteres Objekt im Interface-Teil deklariere:
Delphi-Quellcode:
TVisblePanel = class (TCustomPanel)
published
property OnChangeVisible;
property Visible;
end;
Welchen Vorteil habe ich dadurch?
Ganz Einfach, ich kann innerhalb der
Unit bzw. der Komponentensammlung auf die deklarierten
Eigenschaften der Objekte zugreifen.
Innerhalb einer
Unit, also mehrere Objekte mit dem gleichen Vorfahren kein Problem:
Delphi-Quellcode:
...
TCustomPanel = class(TGraphicControl)
private
FsLabelAdd: TLabel;
...
end;
TButtonPanel = class(TCustomPanel)
...
end;
...
implementation
...
procedure TButtonPanel.SetVisible(Value: Boolean);
begin
TControl(Self).Visible := Value;
FsLabelAdd := 'XX';
end;
...
.
Und wenn beide Objekte in verschiedenen Units sind? Zugriff nicht möglich!
Daher also, eher so:
Delphi-Quellcode:
...
TACustomPanel = class(TCustomPanel)
private
FsLabelAdd: TLabel;
procedure SetLabelAdd(Value : String);
function GetLabelAdd : String;
...
protected
property LabelAdd: string read GetLabelAdd write SetLabelAdd;
end;
TButtonPanel = class(TACustomPanel)
...
end;
...
implementation
...
procedure TButtonPanel.SetLabelAdd(Value: String);
begin
if Assigned(TControl(Self).LabelAdd) then TControl(Self).LabelAdd := Value;
end;
...
procedure TButtonPanel.GetLabelAdd : String;
begin
if Assigned(TControl(Self).LabelAdd) then Result := TControl(Self).LabelAdd.Visible
else Result := '';
end;
procedure TButtonPanel.SetButtonVisible(Value : Boolean);
begin
if Assigned(FButton) then
begin
FButton.Visible := Value;
if FButton.Visible then
if Assigned(TControl(Self).LabelAdd) then TControl(Self).LabelAdd := 'mm';
end
else
if Assigned(TControl(Self).LabelAdd) then TControl(Self).LabelAdd.Free;
end;
Was erreiche ich dadurch?
Ich stelle in den Komponenten/Objekten nur die Eigenschaften in dem Sichtbarkeitsbereich zur Verfügung
die ich als Entwickler auch wünsche und unterbinde auf alle anderen den Zugriff von außen.
Qualitativ stelle ich so mit das zu erwartende Verhalten der Komponenten/Objekte sicher,
nicht nur für mich, sondern auch für andere.
Der Code für den Zugriff innerhalb einer
Unit ist das
schlechtere Beispiel, da die Owner-Komponente nicht
mitbekommt das sich die Sichtbarkeit des Labels geändert hat, daher immer das Beispiel verwenden,
dass die Möglichkeit der Nutzung in verschiedenen Units ermöglicht!
Registriert werden im Abschluss nur die Komponenten/Objekte deren Eigenschaften auch
published sind.
Alles klar?
viele Grüße
Alter Mann
PS Der Code dient nur zur Veranschaulichung und ist nicht getestet!!!