[delphi] Default string property

Pagina: 1
Acties:

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

Topicstarter
Er zijn vast legio andere mensen die dit gevraagd hebben, maar een werkende oplossing heb ik nog niet gevonden. Vandaar deze post. Stel, ik heb een component met een string property. Deze property wil ik by default de waarde "aap" geven. Dat kan natuurlijk zo:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type
  TMyComponent = class(TComponent)
  private
    FProp: string;
    function IsDefault: Boolean;
  published
    property Prop: string read FProp write FProp stored IsDefault;
  end;

implementation

function TMyComponent.IsDefault: Boolean;
begin
Result := FProp <> 'aap';
end;

En dan nog FProp in de constructor op "aap" zetten natuurlijk.

Dit werkt op zich erg goed. Want als je nu "aap" in de object inspector voor deze property invoert, is ie niet meer vet, en wordt ie ook niet meer onterecht in de DFM opgeslagen. Hence, default :)

Het probleem is nu dat een lege string ook niet opgeslagen wordt, waardoor ie weer op "aap" wordt gezet bij het inladen van het form.

Moet ik dit nu met DefineProperties op gaan lossen, of is er een standaard manier voor?

日本!🎌


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Waarom doe je dit niet gewoon via de default specifiek van property? :?

Professionele website nodig?


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

Topicstarter
Omdat default alleen te gebruiken is met ordinal properties. Dus integer types, enums, booleans, dat soort. Maar niet met strings dus.

日本!🎌


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

_Thanatos_ schreef op 10 november 2003 @ 22:53:
Omdat default alleen te gebruiken is met ordinal properties. Dus integer types, enums, booleans, dat soort. Maar niet met strings dus.
* curry684 noteert een vinkje bij 'nieuwe Delphi-kennis opgedaan vandaag' :)

Heb je al eens in de VCL sources gekeken hoe ze dit zelf oplossen? Want dit komt toch meer voor zou je zo zeggen....

Professionele website nodig?


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

Topicstarter
Daar heb ik gekeken, maar de enige die ik zo gauw kon vinden was TFileListBox.Mask, en die heeft precies hetzelfde probleem als mijn code.

Voor de rest worden strings niet zoveel default ingevuld, en dat is natuurlijk enigzins logisch.

日本!🎌


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15-08 18:56

alienfruit

the alien you never expected

waarom zet je de default waardes niet gewoon in de constructor?

[ Voor 6% gewijzigd door alienfruit op 11-11-2003 01:20 ]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

De default property is iets anders dan de beginwaarde die een property heeft. De beginwaarde stel je in de constructor in:
Delphi:
1
2
3
4
5
constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FProp := 'aap';
end;
Je gebruikt trouwens een verwarrende naam voor de storage specifier. IsDefault impliceert species het tegengestelde van wat de storage specifier doet, namelijk aangeven of de property moet worden opgeslagen. De property wordt in jouw geval alleen opgeslagen als IsDefault waar is, terwijl een property juist hoort te worden opgeslagen als de waarde niet default is. Oplossing: hernoem IsDefault naar IsNotDefault of nog duidelijker IsStored:
Delphi:
7
    property Prop: string read FProp write FProp stored IsStored;

Een goede grap mag vrienden kosten.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

Topicstarter
Klopt, het is ook quick&dirty. En zoals ik in m'n startpost aangaf heb ik de waarde ook in de constructor opgegeven, zoals gebruikelijk bij default waarden.

Maar het probleem is niet het maken van een default string waarde, het probleem is dat een lege string niet opgeslagen wordt, terwijl ik met die IsDefault (of hoe ik em dan ook zal noemen) methode aangeef dat dat wel moet.

日本!🎌


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Nu ik de mogelijkheid heb gehad om het te testen, zie ik dat het helemaal klopt wat je zegt. Daarom een werkende oplossing waarbij je zelf streamingmechanisme van de component aanpast.

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
type
  TMyComponent = class(TComponent)
  private
    FTest: string;
    procedure WriteTest(Writer: TWriter);
  protected
    procedure DefineProperties(Filer: TFiler); override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Test: string read FTest write FTest stored False;
  end;

...

const
  TestDefault = 'test';

procedure TMyComponent.WriteTest(Writer: TWriter);
begin
  Writer.WriteString(FTest);
end;

procedure TMyComponent.DefineProperties(Filer: TFiler);

  function TestStored: Boolean;
  begin
    if Assigned(Filer.Ancestor) then
      Result := FTest <> TMyComponent(Filer.Ancestor).FTest
    else
      Result := FTest <> TestDefault;
  end;

begin
  inherited DefineProperties(Filer);
  Filer.DefineProperty('Test', nil, WriteTest, TestStored);
end;

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FTest := TestDefault;
end;
Als je in regel 36 de naam van de dummy property ('Test') precies gelijk houdt aan de werkelijke naam van de property, werkt dit perfect.

Een goede grap mag vrienden kosten.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

Topicstarter
Wow, moedig, om met DefineProperties aan de haal te gaan :)

Ik zal je oplossing morgen gaan testen, maar het ziet er veelbelovend uit.

/edit
Yes het werkt _/-\o_

[ Voor 11% gewijzigd door _Thanatos_ op 12-11-2003 19:32 ]

日本!🎌

Pagina: 1