Delphi-PRAXiS

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/)
-   -   Delphi Eigene Property - Zur Runtime wieder zurückgesetzt (https://www.delphipraxis.net/77657-eigene-property-zur-runtime-wieder-zurueckgesetzt.html)

Neutral General 22. Sep 2006 15:38


Eigene Property - Zur Runtime wieder zurückgesetzt
 
Hi,

Also ich bin ja gerade ne Property mit dem PropertyEditor am basteln.. Also das klappt auch soweit schon...
Während der Designtime wird alles richtig angezeigt. Wenn ich das Programm aber starte dann ist die Komponente im Ur-Zustand :(

Delphi-Quellcode:
procedure Register;
begin
  RegisterPropertyEditor(TypeInfo(TDPListItems), nil, '', TDPItemPropEdit);
end;

procedure TDPItemPropEdit.Edit;
var Dlg: TDPListItemsEditForm;
begin
  Dlg := TDPListItemsEditForm.Create(Application);
  try
    with Dlg do
    begin
      DPItems := TDPListItems(GetOrdValue);
      ShowModal;
    end;
  finally
    FreeAndNil(Dlg);
  end
end;

function TDPItemPropEdit.GetAttributes: TPropertyAttributes;
begin
  Result := [paDialog];
end;
Die EditForm:

Delphi-Quellcode:
procedure TDPListItemsEditForm.FormShow(Sender: TObject);
var i: Integer;
begin
  // "Laden"
  for i:= 0 to DPItems.Count-1 do
   ListBox1.Items.Add(DPItems[i].Caption);
  DPItems.Clear;
end;

procedure TDPListItemsEditForm.Button2Click(Sender: TObject);
var i: Integer;
begin
  // OK Button.. Properties werden gesetzt.. der Property editor wird geschlossen
  for i:= 0 to ListBox1.Count-1 do
  begin
    DPItems.Add(ListBox1.Items[i]);
  end;
  Close;
end;

procedure TDPListItemsEditForm.Button1Click(Sender: TObject);
begin
  ListBox1.Items.Add(Edit1.Text)
end;
Woran kann das liegen? :|

Gruß
Neutral General

MaBuSE 22. Sep 2006 16:10

Re: [Eigene Property] Designtime->OK Runtime-> :|
 
Zitat:

Zitat von Neutral General
Woran kann das liegen?

Ich verstehe Dein Problem nicht.
Poste mal mehr Informationen, Screenshot mit Beisp., ...

[edit]
Die Component- und Property-Editoren werden ja nur in der IDE benutzt.
Zur Laufzeit werden sie nicht aufgerufen, bzw sind gar nicht in der Exe enthalten.
Sie solten also keine Programmlogik enthalten. Sie dienen nur dem komfortablen Zuweisen von Werten in der IDE.
[/edit]

Neutral General 22. Sep 2006 16:16

Re: [Eigene Property] Designtime->OK Runtime-> :|
 
Liste der Anhänge anzeigen (Anzahl: 2)
@ MaBuSE Edit: Ja das weiß ich ja... Guck mal

EDIT: Der Editor ist noch nicht so schön aber das is ja auch nur mal um zu gucken obs geht.. das die ListBox nach dem start so klein ist, kommt von ner Art AutoSize-Funktion die das Ding hat ;)

MaBuSE 22. Sep 2006 16:39

Re: [Eigene Property] Designtime->OK Runtime-> :|
 
Zitat:

Zitat von Neutral General
@ MaBuSE Edit: Ja das weiß ich ja... Guck mal

EDIT: Der Editor ist noch nicht so schön aber das is ja auch nur mal um zu gucken obs geht.. das die ListBox nach dem start so klein ist, kommt von ner Art AutoSize-Funktion die das Ding hat ;)

Dein Problem ist folgendes:

Normale Properties werden direkt in der Formulardatei (*.dfm) gespeichert.
Mit Objekten funktioniert das aber nicht.

Du mußt Dich also selbst darum kümmern die Infos in der DFM zu speichern.

Hier findest Du weitere Infos: Delphi-Referenz durchsuchenDefineProperties (Methode von TComponent)


Das müsste so oder so ähnlich gehen.
(Habe ich jetzt nicht in Delphi getestet ;-) )

Delphi-Quellcode:
...
type
  TMyComp = class(TComponent)
  private
    FMyData: TMyData;
    procedure ReadMyData(Reader: TReader);
    procedure WriteMyData(Writer: TWriter);
...
  protected
    procedure DefineProperties(Filer: TFiler);
...
  published
    MyData: TMyData read FMyData write FMyData;
...

procedure TMyComp.DefineProperties(Filer: TFiler);
  function WriteData: Boolean;
  begin
    if Filer.Ancestor <> nil then
      Result := not FMyData.IsEqual(TMyComp(Filer.Ancestor).FMyData) else
      Result := FMyData.Count > 0;
  end;

begin
  inherited DefineProperties(Filer);
  Filer.DefineProperty('MyData', ReadMyData, WriteMyData, WriteData);
end;

procedure TMyComp.ReadMyData(Reader: TReader);
begin
  Reader.ReadValue;
  Reader.ReadCollection(MyData);
end;

procedure TMyComp.WriteMyData(Writer: TWriter);
begin
  Writer.WriteCollection(MyData);
end;
...

Neutral General 22. Sep 2006 16:54

Re: [Eigene Property] Designtime->OK Runtime-> :|
 
EHm ja danke.. Aber copy&paste geht nicht weil zum Beispiel meine Klasse kein IsEqual hat oder weil ich nicht mit dem Writer meine Klasse schreiben kann weil meine Klasse nicht vom Typ TCollection ist usw.. Außerdem versteh ich das irgendwie nicht genau.. :(

Kannst du mirs eventuell genauer erklären ? :stupid: :|

Gruß
Neutral General

MaBuSE 22. Sep 2006 17:02

Re: [Eigene Property] Designtime->OK Runtime-> :|
 
Zitat:

Zitat von Neutral General
Kannst du mirs eventuell genauer erklären ? :stupid: :|

Kannst Du nicht wie schon angedeutet die Hilfe lesen?

Delphi-Referenz durchsuchenDefineProperties (Methode von TComponent)

Dort steht:
Zitat:

Die Methode DefineProperties legt Methoden fest, mit denen die nicht als published deklarierten Daten eines Objekts in einem Stream (z.B. in einer Formulardatei) gespeichert werden können.

Delphi-Syntax:
procedure DefineProperties(Filer: TFiler); override;

Beschreibung
TComponent überschreibt die in TPersistent definierte Methode DefineProperties, um Werte für die Eigenschaften Top und Left "vorzutäuschen". Auf diese Weise können Komponenten, die keine Steuerelemente sind, zur Entwurfszeit manipuliert werden. Die Eigenschaften Top und Left sind allerdings nicht als published deklariert, da solche Komponenten zur Laufzeit nicht auf dem Bildschirm sichtbar sind.

DefineProperties ist virtuell und kann somit von untergeordneten Klassen überschrieben werden. Wenn Sie die Methode DefineProperties überschreiben, beachten Sie, dass die Eigenschaft Ancestor von TFiler gesetzt sein könnte und dass diese Eigenschaft festlegen kann, ob Eigenschaften in den Stream geschrieben werden.

DefineProperties wird automatisch als Teil des Komponenten-Streaming-Systems aufgerufen. Rufen Sie die Methode nicht direkt auf.
Es gibt dort sogar ein Beispiel:
Zitat:

ReadBoolean, WriteBoolean, ReadComponent, WriteComponent, DefineProperties, DefineProperty, Ancestor (Beispiel)
Dieses Beispiel zeigt, wie eine als nicht published deklarierte Eigenschaft, deren Wert eine zur Laufzeit erzeugte Komponente ist, geladen und gespeichert wird. Die beiden Methoden LoadCompProperty und StoreCompProperty werden zum Laden und Speichern des Eigenschaftswerts definiert. Es wird auch die Methode DefineProperties überschrieben, in der diese beiden Routinen an das Streaming-System übergeben werden. Die Methode DefineProperties überprüft die Eigenschaft Ancestor von TFiler, damit kein Eigenschaftswert in geerbten Formularen gespeichert wird.
Delphi-Quellcode:
procedure TSampleComponent.LoadCompProperty(Reader: TReader);
begin
  if Reader.ReadBoolean then
    MyCompProperty := Reader.ReadComponent(nil);
end;

procedure TSampleComponent.StoreCompProperty(Writer: TWriter);

begin
  Writer.WriteBoolean(MyCompProperty <> nil);
  if MyCompProperty <> nil then
    Writer.WriteComponent(MyCompProperty);
end;

procedure TSampleComponent.DefineProperties(Filer: TFiler);

  function DoWrite: Boolean;
  begin
    if Filer.Ancestor <> nil then { Auf geerbten Wert prüfen }
    begin
      if TSampleComponent(Filer.Ancestor).MyCompProperty = nil then
        Result := MyCompProperty <> nil
      else if MyCompProperty = nil or
         TSampleComponent(Filer.Ancestor).MyCompProperty.Name <> MyCompProperty.Name then
        Result := True
      else Result := False;

    end
    else { Kein geerbter Wert, auf Standardwert (nil) prüfen }
      Result := MyCompProperty <> nil;
  end;
begin
  inherited; { Basisklassen das Definieren von Eigenschaften ermöglichen }
  Filer.DefineProperty('MyCompProperty', LoadCompProperty, StoreCompProperty, DoWrite);
end;

Wo ist Dein Problem?

Brauchst Du ein Tutorial wie man die Hilfe aufruft?

Ich bin nun im Wochenende, ... bis Montag.

Sharky 22. Sep 2006 17:13

Re: [Eigene Property] Designtime->OK Runtime-> :|
 
Hai Neutraler General,

kannst Du den Titel deines Postings bitte so anpassen das er, wie alle anderen auch, als Frage im Forum gesehen wird?

dur die [xx] sieht es, für mich, so aus als wäre das etwas wichtiges.


Danke.

Neutral General 22. Sep 2006 17:53

Re: Eigene Property - Zur Runtime wieder zurückgesetzt
 
So hab das jetzt mit ner BinaryProperty gemacht.. aber wenn ich die Exe starte dann bekomm ich diesen Fehler:

Zitat:

---------------------------
Application Error
---------------------------
Exception EReadError in module Project1.exe at 00017497.

Error reading DPListBox1.Items: Invalid property value.


---------------------------
OK
---------------------------
:|

Meine Lese/Schreibe proceduren:

Delphi-Quellcode:
procedure TDPListBox.ReadMyData(AStream: TStream);
var i: Integer;
    tmp: Integer;
begin
  AStream.Read(tmp,SizeOf(Integer));
  FItems.FCount := tmp;
  SetLength(FItems.FItems,Count);
  for i:= 0 to Count-1 do
  begin
    FItems[i] := TDPListItem.Create(Self);
    AStream.Read(tmp,SizeOf(Integer));
    SetLength(FItems[i].FCaption,tmp);
    AStream.Read(FItems[i].FCaption[1],tmp);

    AStream.Read(FItems[i].FImageIndex,SizeOf(Integer))
  end;
end;
Delphi-Quellcode:
procedure TDPListBox.WriteMyData(AStream: TStream);
var i: Integer;
    tmp: Integer;
begin
  tmp:= Count;
  AStream.Write(tmp,SizeOf(Integer));
  for i:= 0 to Count-1 do
  begin
    tmp := Length(FItems[i].FCaption);
    AStream.Write(tmp,SizeOf(Integer));
    AStream.Write(FItems[i].FCaption[1],tmp);
    AStream.Write(FItems[i].FImageIndex,SizeOf(Integer));
  end;
end;
Und die Define Properties Procedure:

Delphi-Quellcode:
procedure TDPListBox.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  Filer.DefineBinaryProperty('Items',ReadMyData, WriteMyData, Count > 0);
end;
Ich bin naah dran aber wie gehts weiter ?^^

Gruß
Neutral General

Neutral General 23. Sep 2006 10:54

Re: Eigene Property - Zur Runtime wieder zurückgesetzt
 
Biddöö :stupid:
Ich bin sooo nahhhh dran :)

Also im Forumlar steht z.B sowas:

Delphi-Quellcode:
...
object DPListBox1: TDPListBox
    Left = 208
    Top = 64
    Width = 385
    Height = 113
    Footer = ftRect
    Items = {
      020000000500000048616C6C6F000000000000000004000000546F6C6C000000
      0000000000}
  end

K.S.M. 25. Mai 2011 22:46

AW: Eigene Property - Zur Runtime wieder zurückgesetzt
 
Ich weiß, ist jetzt bissel spät für eine Antwort, aber ich habe mich gerade selbst mit dem Thema auseinandergesetzt.

Wenn du bei deiner Komponente ein Unterobjekt vom Typ TPersistent hast, dann baue in dieses die Struktur mit DefineProperties ein, so wie es oben steht. In der .dfm-Datei steht dann der Eintrag ähnlich vermerkt wie:
Delphi-Quellcode:
Unterobjekt.Untereigenschaft
oder ähnlich. Hoffe, das ist für den einen oder anderen hilfreich, bei mir funktioniert es so auf jeden Fall und wird auch von der VCL (z.B. bei Strings-Eigenschaft des TMemo) verwendet.

lg K.S.M. ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:32 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