Eigene Komponente reagiert nicht auf Objektinspektor

    Eigene Komponente reagiert nicht auf Objektinspektor

    Hallo und einen guten Tag!

    Ganz neu hier hat es mich zu Euch geführt, die Suchfunktion brachte mich nicht weiter, daher mein Problem:

    Ich habe eine eigene Komponente erzeugt, die als Basisklasse ein TPanel hat, welches dann mehrere Labels, Buttons usw. enthält.
    Auch besitzt diese neue Komponente eine Property "Kundenname", für die ich auch ein GetKundenname und SetKundenname implementiert habe.
    Im Create bzw. auch im SetKundenname wird in dem Label dieser Kundenname angezeigt.

    Erzeuge ich solch ein Panel per Code
    Panel := TMyPanel.create(Form1);
    Panel.Parent := Form1;
    Panel.SetKundenname('Müller');

    wird dieser Name korrekt im Label angezeigt.

    Im create des Labels wird der Kundenname mit 'Meier' voreingestellt und auch so im Objektinspektor angezeigt.
    Ändere ich diesen nun im Objektinspektor auf 'Müller', tut sich in einer auf die Form gelegten Komponente gar nichts! Da steht weiterhin 'Meier' drin.

    Ich google seit 2 tagen, aber komme nicht weiter, kann mir bitte jemand einen Denkanstoß verpassen?

    Ciao
    Stefan
    ​Ne, das war etwas voreilig! In der tat hab ich nicht so ganz kapiert, was dein Problem ist...


    Ich habe die Komponente in der Palette zur Auswahl, kann sie auf ein Formular pappen und wenn ich draufklicke zeigt der Objektinspektor die Eigenschaften der Komponente an.
    Hier finden sich alle Eigenschaften des Vorfahren (TPanel) und auch meine neuen zusätzlichen Eigenschaften.

    In der Komponente gibt es ein SetKundenname welches der Property Kundenname den Wert zuweist und gleichzeitig dies in einem Label anzeigt.

    Ändere ich die Property Kundenname im Objektinspektor wird aber auf dem Formular in der Komponente dieser nicht aktualisiert...

    Macht man das z.B. mit einem stinknormalen Label, wird dieses auf dem Formular mit geändertem Text angezeigt...

    Ich möchte nun bei meiner eigenen Komponente ebenfalls erreichen, dass bei Änderung der Eigenschaft Kundenname dies auf der Komponente korrekt angezeigt wird...

    Ciao
    Stefan
    Wie sieht denn die Setter-Methode für den Kundennamen aus ?
    Glückauf

    Herr, wirf Hirn vom Himmel

    Ein Leben ohne Möpse ist möglich, aber sinnlos ( Loriot )
    Der beste Platz für Politiker ist das Wahlplakat. Dort ist er tragbar, geräuschlos und leicht zu entfernen ( Loriot )

    Es gibt Leute, die fühlen sich überall gedemütigt, wo sie nicht frech sein dürfen ( Otto Weiss )

    cckLoud schrieb:

    Hast du schon mal probiert,die Komponte/die betroffenen Subkomponenten neu zu zeichnen (invalidate), wenigstens im Entwurfsmodus?

    Deswegen meine Frage. Normalerweise sieht eine Setter-Methode so aus :

    Delphi-Code

    1. procedure SetKunde ( Value : String);
    2. begin
    3. if FKunde <> Value then
    4. begin
    5. FKunde := Value;
    6. Invalidate;
    7. end;
    8. end;
    Glückauf

    Herr, wirf Hirn vom Himmel

    Ein Leben ohne Möpse ist möglich, aber sinnlos ( Loriot )
    Der beste Platz für Politiker ist das Wahlplakat. Dort ist er tragbar, geräuschlos und leicht zu entfernen ( Loriot )

    Es gibt Leute, die fühlen sich überall gedemütigt, wo sie nicht frech sein dürfen ( Otto Weiss )
    Meine Setter-Methode sieht folgendermassen aus:

    Quellcode

    1. procedure TMyPanel.SetKundename(Value: string);
    2. begin
    3. if FKundename <> Value then
    4. begin
    5. FKundename := Value;
    6. lab2.Text := FKundename;
    7. end;
    8. end;


    Quellcode

    1. property Kundename: string read FKundename write FKundename;


    Invalidate habe ich versucht einzubauen, wirft aber Compilerfehler, TPanel (ist der Vorfahr meiner Komponente) kennt kein Invalidate :(

    Außerdem wird ja bei Aufruf im Code per SetKundename auf brav aktualisiert, aber nicht wenn ich die Property direkt über den Objektinspektor setze!
    Dann bleibt der Kundenname der auf das Formular gepappten Komponente unverändert!

    Hat noch jemand eine Idee oder eine "Minikomponente" zum "Abgucken" was bei mir anders ist?

    Ciao
    Stefan
    Dann probier halt sowas wie "lab2.invalidate"!

    Noch ein Hinweis: Variablen/Komponentennamen sollten sprechend sein, also auf den Verwendungszweck hinweisen. Das macht üblicherweise den Code viel einfacher interpretierbar.

    "lab2" ist definitiv _nicht_ sprechend. Stell dir mal vor, du hättest da was größeres mit vielleicht 50 Labels - du würdest dech nicht mehr auskennen. "labelKundenname" würde dir dann weiterhelfen - genau so wie zB "ButtonBeenden" (statt zb "Button1"). Die generierten Namen (bei Labels) sind nur dann verwendbar, wenn sie als nicht zu ändernder Text verwendet wird, der ausschliesslich im OI gefüllt wird.

    cckloud

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „cckLoud“ ()

    sko schrieb:

    Meine Setter-Methode sieht folgendermassen aus:

    Quellcode

    1. procedure TMyPanel.SetKundename(Value: string);
    2. begin
    3. if FKundename <> Value then
    4. begin
    5. FKundename := Value;
    6. lab2.Text := FKundename;
    7. end;
    8. end;


    Quellcode

    1. property Kundename: string read FKundename write FKundename;

    Du hast zwar einen Setter geschrieben, benutzt ihn aber nicht.

    Delphi-Code

    1. property Kundename: string read FKundename write SetKundename;

    Damit müsste beim Setzen eines Wertes der Setter auch durchlaufen werden.
    10 Minuten Nachdenken ersparen oftmals 10 Stunden Fehlersuche.
    Mist, ich komme irgendwie nicht weiter...

    Hier mal eine Testkomponente , bestehend aus einem Panel und einem Label:

    Quellcode

    1. unit SKTest;
    2. interface
    3. uses
    4. System.SysUtils, System.Classes, FMX.Types, FMX.Controls,
    5. FMX.Controls.Presentation, FMX.StdCtrls;
    6. type
    7. TestPanel = class(TPanel)
    8. private
    9. { Private-Deklarationen }
    10. Testlabel: TTestlabelel;
    11. FTestlabeltext : string;
    12. protected
    13. { Protected-Deklarationen }
    14. public
    15. { Public-Deklarationen }
    16. constructor Create(AOwner: TComponent); override;
    17. destructor Destroy; override;
    18. procedure SetTestlabelText(Value: string);
    19. function GetTestlabeltext: string;
    20. published
    21. { Published-Deklarationen }
    22. property Testlabeltext: string read FTestlabeltext write FTestlabeltext;
    23. end;
    24. procedure Register;
    25. implementation
    26. procedure Register;
    27. begin
    28. RegisterComponents('Test', [TestPanel]);
    29. end;
    30. constructor TestPanel.Create(AOwner: TComponent);
    31. begin
    32. inherited Create(AOwner);
    33. FTestlabeltext := 'Hallo';
    34. Testlabel := TTestlabelel.Create(self);
    35. Testlabel.Parent := self;
    36. Testlabel.Visible:= true;
    37. Testlabel.Text := FTestlabeltext;
    38. end;
    39. destructor TestPanel.Destroy;
    40. begin
    41. Testlabel.Free;
    42. inherited Destroy;
    43. end;
    44. procedure TestPanel.SetTestlabeltext(Value: string);
    45. begin
    46. if FTestlabeltext <> Value then
    47. begin
    48. FTestlabeltext := Value;
    49. Testlabel.Text := FTestlabeltext;
    50. end;
    51. end;
    52. function TestPanel.GetTestlabeltext: string;
    53. begin
    54. Result := FTestlabeltext;
    55. end;
    56. end.


    Pappt man diese auf ein Formular und ändert die Property Testlabeltext ändert sich an der Darstellung auf dem Formular nichts :(

    Ändert man zur Laufzeit per SetTestLabelText geht es...

    Was fehlt hier damit auch im Entwurfsmodus Properties korrekt dargestellt wird?

    Danke
    Ciao
    Stefan
    Mann, hst du nicht durchgelesn, was DeddyH geschrieben hat?

    Ums noch einmal auf den Punkt zu bringen: du verwendest deine Properties FALSCH !!! Lies doch hier in den Tutorials durch, wie das geht.

    Dein Fehler: du sollst nicht die Methode "SetTestlabelText" nutzen, um den Wert zu setzen, sondern die Property "Testlabeltext". Also in dieser weise:

    MyTestPanel .Testlabeltext := 'Irgendein Text"

    wenn du das nicht so machst, kannst du dir die Property auch sparen. Ausserdem must du noch die Definition der Property auf Vordermann bringen:

    property Testlabeltext: string read GetTestlabelTextwrite SetTestlabelText;

    Wenn du jetzt die obige zuweisung ausführst, ruft Delphi intern die Methode "SetTestlabelText" auf und du kannst dir das sparen. Weiterhin soltest du Setter und Getter (SetTestlabelText und GetTestlabeltext) als Private oder Protected definieren, damit du gar nicht erst auf Idee kommst, sie nochmals anzuwenden.

    Und damit denn alles auch funktioniert, musst du noch die Settermethode anpassen: mit dem ersten befehl sollte die Variable "FTestlabeltext" gesetzt werden, also

    procedure TestPanel.SetTestlabeltext(Value: string);
    begin
    FTestlabeltext := Value;
    if FTestlabeltext <> Value then
    begin
    FTestlabeltext := Value;
    Testlabel.Text := FTestlabeltext;
    end;
    end;

    Dann sollte es funktionieren. Aber noch mal: bevor du da anfängst, rumzuprogrammieren (oder zumindest damit zusammen) :

    LIES DIE GRUNDLAGEN DURCH!!!!

    cckLoud
    Bist du dir damit wirklich sicher ? :P

    cckLoud schrieb:


    procedure TestPanel.SetTestlabeltext(Value: string);
    begin
    FTestlabeltext := Value;
    if FTestlabeltext <> Value then
    begin
    FTestlabeltext := Value;
    Testlabel.Text := FTestlabeltext;
    end;
    end;
    Glückauf

    Herr, wirf Hirn vom Himmel

    Ein Leben ohne Möpse ist möglich, aber sinnlos ( Loriot )
    Der beste Platz für Politiker ist das Wahlplakat. Dort ist er tragbar, geräuschlos und leicht zu entfernen ( Loriot )

    Es gibt Leute, die fühlen sich überall gedemütigt, wo sie nicht frech sein dürfen ( Otto Weiss )

    sko schrieb:

    So, ich habe Eure Ratschläge befolgt, das einzige, was ich ändern musste, war das Verschieben der Getter und Setter in den private-Bereich, dann spielt der Objektinspektor auch mit :)

    Der private-Bereich hat damit nichts zu tun. Im Objektinspektor landen die properties, die als published deklariert sind. Wo die Getter und Setter stehen, ist egal
    Glückauf

    Herr, wirf Hirn vom Himmel

    Ein Leben ohne Möpse ist möglich, aber sinnlos ( Loriot )
    Der beste Platz für Politiker ist das Wahlplakat. Dort ist er tragbar, geräuschlos und leicht zu entfernen ( Loriot )

    Es gibt Leute, die fühlen sich überall gedemütigt, wo sie nicht frech sein dürfen ( Otto Weiss )