Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Property's "stored" bug... (https://www.delphipraxis.net/207257-propertys-stored-bug.html)

BigAl 8. Mär 2021 10:51

Property's "stored" bug...
 
Hallo zusammen,

ich habe eben einen Bug entdeckt. Ich gehe mal davon aus, dass es so ist, habe auf jeden Fall mal einen case dazu aufgemacht: RSP-33237

Folgendes Problem:

Properties von Komponenten (abgeleitet von TPersistent) welche mit "stored" prüfen ob die Eigenschaft gespeichert werden soll werden nicht gespeichert wenn entweder die stored-Funktion "False" zurück liefert (ist korrekt) oder Wert der Eigenschaft "0" ist (das ist falsch). Das ist natürlich fatal, da im Falle von "0" beim nächsten laden wieder der vorgegeben Wert in der Variable steht...

Also: aufpassen :-)

Oder habe ich was übersehen?

Gruß
Alex

Stevie 8. Mär 2021 11:16

AW: Property's "stored" bug...
 
Das ist leider ein bisschen schäbig gelöst - das Kernproblem liegt in System.Classes.IsDefaultFloatProp - dort wird nämlich 0 immer als Standard betrachtet, auch wenn man explizit eine storedproc angegeben hat.
Allerdings kann man dort sehen, dass nach dem Default Attribut geschaut wird.

Lösung also:

Delphi-Quellcode:
[Default(5)]
über die Eigenschaft schreiben und schon klappt es.

himitsu 8. Mär 2021 11:47

AW: Property's "stored" bug...
 
Dann wird doch die 5, bzw. 5.0 nicht gespeichert?

Allerdings sollte das DEFAULT garnicht verwendet werden, wenn ein STORED angegeben ist, womit das ein Fehler wäre. :gruebel:



Und ja, das "normale" Default an Properties ist nur für ordinale Typen nutzbar (Byte bis Integer und Enums bzw. Sets)

Daher wurde schon vor Längerem das [Default]-Attribut hinzugefügt. (geht auch für Strings)


Und natürlich müssen Atttribute vor/über dem stehen, für was sie gelten.

BigAl 8. Mär 2021 11:56

AW: Property's "stored" bug...
 
Ich denke das einzige was ich momentan machen kann ist die "stored" wegzulassen und somit die Properties immer speichern (außer sie sind 0). Sieht dann halt wieder im Objektinspektor doof aus wenn die alle fett sind obwohl die auf default stehen.

Vielleicht nimmt sich dem Bug bei Emba ja mal einer an. Meiner Meinung ist das ein Bug...

Sinspin 8. Mär 2021 11:57

AW: Property's "stored" bug...
 
An einigen Stellen nutzen DevExpress und mittlerweile auch Emba ein weiteres Property "AssignedValues" um zwischen Defaultwert und zugewiesenem Wert zu unterscheiden.
Das wird leider noch nicht konsequent durchgezogen.

Das ist ein Bitset das einen Eintrag pro Property hat. Trägt man einen Wert in ein Property ein, geht das passende Bit auf true. Setzt man es wieder auf false ist das Property wieder default.

Stevie 8. Mär 2021 12:24

AW: Property's "stored" bug...
 
Zitat:

Zitat von himitsu (Beitrag 1484639)
Dann wird doch die 5, bzw. 5.0 nicht gespeichert?

So isset, und so sollet - denn die storedproc sagte ja
Delphi-Quellcode:
Result := not SameValue(FMyValue, 5.0);
Zitat:

Zitat von BigAl (Beitrag 1484640)
Ich denke das einzige was ich momentan machen kann ist die "stored" wegzulassen und somit die Properties immer speichern (außer sie sind 0). Sieht dann halt wieder im Objektinspektor doof aus wenn die alle fett sind obwohl die auf default stehen.

Vielleicht nimmt sich dem Bug bei Emba ja mal einer an. Meiner Meinung ist das ein Bug...

Eventuell hab ich mich zu verschwurbelt ausgedrückt, aber ich stimme dir zu, dass es ein Bug ist.
5 nicht speichern kann man abbilden, wie ich oben schrieb. Ich glaube, man kann dann sogar die storedproc ganz weglassen und einfach nur das Attribut nutzen.
Denke dann aber daran, diesen Wert auch im ctor explizit zu setzen.

Rolf Frei 8. Mär 2021 13:54

AW: Property's "stored" bug...
 
Der Datentyp hat doch keinerlei Einfluss darauf, ob das Property gespeichert wird oder nicht. Wenn da "stored False" ist, darf überhaupt nichts gespeichert werden. Im DFM darf das Property dann überhaupt nicht vorhanden sein. Das ist die Funktion dieser Direktive. Auch der Defaultwert hat damit überhaupt nichts zu tun. Dafür gibt es "default X" und das entsprechende Zuweisen an das Feld im Create.

OP, ich sehe da nichts Falsches. Dass ein Property Integer 0 oder ein leerer String nicht gespechert wird, ist absolut richtig. Das sind ja die Anfangswerte auf die du deine Felder im Create initialisierst oder machst du das nicht? Dann ist der Fehler bei dir. Du solltest alle Felder in Create initialisieren.

EDIT:
Eventuell habe ich diene Frage falsch verstanden. Setzt du den einen default Wert beim Property? Also so...

Delphi-Quellcode:
property Abc: Integer read FAbc write FAbc default 5 stored IsStored;

TMyOvjet.Create...
begin
  FAbc = 5;
  inherited;
end;
In diesem Fall dürfte das Property nur dann nicht gepseichert werden, wenn es den Wert 5 hat oder IsStored False liefert. Verstehe cih das nun richtig, dass das Property auch nicht gespeichert wird, wenn es den Wert 0 hat. Das wäre dann in der Tat ein Bug, insofern dein Property so definiert ist wie oben in meinem Beispiel.

Uwe Raabe 8. Mär 2021 14:14

AW: Property's "stored" bug...
 
Zitat:

Zitat von Rolf Frei (Beitrag 1484652)
Wenn da "stored False" ist, darf überhaupt nichts gespeichert werden.

Das wird ja auch gar nicht bemängelt.

Zitat:

Zitat von BigAl (Beitrag 1484632)
werden nicht gespeichert wenn entweder die stored-Funktion "False" zurück liefert (ist korrekt) oder Wert der Eigenschaft "0" ist (das ist falsch)

Das Problem ist hier offenbar, dass stored True zurück liefert, aber trotzdem nichts gespeichert wird, wenn der aktuelle Wert 0 ist. Insofern liegt es schon am falschen (impliziten) Default-Wert.

Es ist aber wohl kein Bug, denn das entspricht zumindest der Dokumentation:
Zitat:

Wenn sich der aktuelle Wert einer Eigenschaft von ihrem default-Wert unterscheidet (oder kein default-Wert vorhanden ist) und stored True ist, wird der Wert gespeichert. Treffen diese Bedingungen nicht zu, wird der Wert nicht gespeichert.

himitsu 8. Mär 2021 14:24

AW: Property's "stored" bug...
 
Passend zum Default gibt es auch NoDefault, um einen zuvor deklarierten Default zu entfernen.

Delphi-Quellcode:
// Varianten mit Specifiers

property MyValue: Single read FMyValue write FMyValue nodefault stored GetMyValueStored;

property MyValue: Single read FMyValue write FMyValue default 5; // das geht nicht, weil Single kein ordinaler Typ ist



// Varianten mit Attributen

[NoDefault]
property MyValue: Single read FMyValue write FMyValue stored GetMyValueStored;

[Default(5)]
property MyValue: Single read FMyValue write FMyValue;



// und auch Stored gibt es als StoredAttribute (aber muß ja nicht sein)

[NoDefault, Stored('GetMyValueStored')]
property MyValue: Single read FMyValue write FMyValue;
Delphi-Referenz durchsuchenDefaultAttribute
Delphi-Referenz durchsuchenNoDefaultAttribute
Delphi-Referenz durchsuchenStoredAttribute


Und ja, das was man als Default deklariert hat, muß auch wirklich dem entsprechen, was der Default der Klasse ist, sonst hat man viel Spaß.


Aber gibt es überhaupt einen Default-Default?
Wenn kein Default angegeben wurde, was hier der Fall ist, dann ist es doch eigentlich ein "Fehler", wenn Delphi hier eigenmächtig "irgendeinen" einen Default verwendet.

Renate Schaaf 8. Mär 2021 14:50

AW: Property's "stored" bug...
 
Geht es hier um float-properties? Der bug ist bekannt seit Delphi 1, wurde angemahnt, und kam zurück mit "as designed". Ray Lischner hat eine Lösung gefunden, ich poste hier mal den Teil einer Komponente für Delphi 1, der die Lösung beinhaltet und erklärt. Falls das nicht das Problem ist, nevermind.

Delphi-Quellcode:
...
  protected
  procedure ReadD2WorldXw(Reader: TReader);
  procedure WriteD2WorldXW(Writer: TWriter);
  procedure DefineProperties(Filer: TFiler); override;
 
  published
  property D2WorldXW: extended read xwd2 write setxwd2 stored false;
  {Don't worry about the stored false in all of these. They get stored:
    see override of DefineProperties. The default storing process never
    writes a value 0 of a float property to the dfm-file and the default
    value set in the constructor is used instead. So if that default is
    <>0, a value 0 can never be set. Overriding DefineProperties fixes it
     (workaround by Ray Lischner).
    Stored false is used, so the property is not stored twice. (Thanks to
    Joe Herb for the tip)}

...

procedure TMathImage.ReadD2WorldXW(Reader: TReader);
begin
  xwd2 := Reader.ReadFloat;
end;

procedure TMathImage.WriteD2WorldXW(Writer:TWriter);
begin
  Writer.WriteFloat(xwd2);
end;

procedure TMathImage.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  with Filer do
  begin
    DefineProperty('D2WorldXW', ReadD2WorldXW, WriteD2WorldXW, true);
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:51 Uhr.
Seite 1 von 2  1 2      

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