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 Änderungen im TFrame auf einem TForm verhindern. (https://www.delphipraxis.net/200524-aenderungen-im-tframe-auf-einem-tform-verhindern.html)

bernau 28. Apr 2019 09:48

Änderungen im TFrame auf einem TForm verhindern.
 
Ich habe ein TFrame auf dem verschiedene Komponenten positioniert sind. Je nach Einstellung werden die Komponenten anders angeordnet. Das mache ich im Create des Frames.

Wenn das Frame auf ein Form platziert wird funktioniert auch alles soweit. Wenn aber im Form eine Komponente des Frame "aus versehen" leicht verschoben wird, dann bleibt diese Komponente dort platziert. Eine Änderung im Create ist nicht mehr möglich. Erst wenn ich "Geerbte Einstellungen wiederherstellen" (Rechter Mausklick auf die Komponente im TForm) verwende, oder den entsprechenden Eintrag in der DFM des Forms lösche, dann funktioniert auch die Änderung im Create wieder.

Ist aber lästig. Vor allem, wenn man die zufällige Änderung nicht bemerkt.

Gibt es die Möglichkeit die Änderungen der Framekomponenten auf der Form grundsätzlich zu verhindern. Oder gibt es eine "vererbte" Funktion im Frame, die aufgerufen wird, nachdem die Form komplett erzeugt wurde?

Uwe Raabe 28. Apr 2019 10:54

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Es gibt eine Option generell die Elemente im Form-Designer vor Verschieben zu schützen: Bearbeiten - Elemente fixieren

Speziell nur für Frame-Instanzen ist mir nichts dergleichen bekannt. Aber das klingt nach einer interessanten Aufgabe für ein Plugin :thumb:

bernau 28. Apr 2019 11:18

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1431202)
Es gibt eine Option generell die Elemente im Form-Designer vor Verschieben zu schützen: Bearbeiten - Elemente fixieren

Ja. aber diese Option fixiert alle Formulare.


Zitat:

Zitat von Uwe Raabe (Beitrag 1431202)
Aber das klingt nach einer interessanten Aufgabe für ein Plugin :thumb:

Juhu. Lass mich wissen, wenn du einen Ansatz hast. :hello:


Im Augenblick helfe ich mit mit Resize des Frames. Das wird irgendwie immer aufgerufen. Beim ersten Durchlauf verschiebe ich dort die Komponenten und merke mir das mit einem Flag, damit diese nur einmal ausgerichtet werden. Ist aber eine Krücke und ein Property "FixateComponents" im Frame wäre schon eine feine Sache.

dummzeuch 28. Apr 2019 14:11

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Ich mache das immer über die Sourcecode-Verwaltung: Beim Einchecken die DFM-Dateien anschauen und alle Änderungen innerhalb des/der Frames rückgängig machen.

Ist zwar nicht ideal, aber hilft. Das kann man natürlich jederzeit machen, nicht nur beim Einchecken.

Alternativ hilft nur ein Plugin (ich kenne keines, weiss auch nicht, ob es überhaupt möglich ist) oder Frames nie im Designer zu einem Formular hinzufügen sondern immer erst zur Laufzeit. Beim Design dann Panels als Platzhalter verwenden. (Es soll sogar Leute geben, die statt Panels ein Image mit einem Screenshot des Frames verwenden.)

Der schöne Günther 28. Apr 2019 20:53

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von dummzeuch (Beitrag 1431221)
Ich mache das immer über die Sourcecode-Verwaltung: Beim Einchecken die DFM-Dateien anschauen und alle Änderungen innerhalb des/der Frames rückgängig machen.

Ich ebenso. Zwar ziemlich schade da man die gleiche Zeit auch für etwas Sinnvolles verwenden könnte, aber immer noch zeiteffektiver als sich mit den Folgen herumzuplagen 😎

Zitat:

Zitat von dummzeuch (Beitrag 1431221)
oder Frames nie im Designer zu einem Formular hinzufügen sondern immer erst zur Laufzeit. Beim Design dann Panels als Platzhalter verwenden. (Es soll sogar Leute geben, die statt Panels ein Image mit einem Screenshot des Frames verwenden.)

"nie" finde ich jetzt etwas extrem. Mann kann doch sowohl, als auch.

Trotzdem ein sinnvoller Ansatz, besonders bei großen/verschachtelten Frames. Weiterer Bonus: Der Formular-Designer baut sich schneller auf.

uligerhardt 28. Apr 2019 23:44

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Ich glaube mich zu erinneren, dass Frames sich so verhalten, wenn man eine Komponente draus macht.

bernau 29. Apr 2019 09:01

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1431240)
Zitat:

Zitat von dummzeuch (Beitrag 1431221)
Ich mache das immer über die Sourcecode-Verwaltung: Beim Einchecken die DFM-Dateien anschauen und alle Änderungen innerhalb des/der Frames rückgängig machen.

Ich ebenso. Zwar ziemlich schade da man die gleiche Zeit auch für etwas Sinnvolles verwenden könnte, aber immer noch zeiteffektiver als sich mit den Folgen herumzuplagen 😎

Zitat:

Zitat von dummzeuch (Beitrag 1431221)
oder Frames nie im Designer zu einem Formular hinzufügen sondern immer erst zur Laufzeit. Beim Design dann Panels als Platzhalter verwenden. (Es soll sogar Leute geben, die statt Panels ein Image mit einem Screenshot des Frames verwenden.)

"nie" finde ich jetzt etwas extrem. Mann kann doch sowohl, als auch.

Trotzdem ein sinnvoller Ansatz, besonders bei großen/verschachtelten Frames. Weiterer Bonus: Der Formular-Designer baut sich schneller auf.

Ich bin tatsächlich ein Freund vom Erzeugen von Frames während der Laufzeit. Vor allem wenn Frames auf einem Pagecontrol platziert sind und die ganze Clientfläche benutzen. In ein paar Fällen sind aber Frames zwischen anderen Frames oder sonstigen Komponenten platziert. Dann ist es schon besser, diese zur Designtime zu platzieren.

Beim Einchecken in die Sourcecodeverwaltung kann man zwar die Änderungen kontrollieren. Aber mal ganz ehrlich...... an der Stelle will ich nichts mehr kontrollieren.

Der schöne Günther 29. Apr 2019 09:18

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Von wollen hat auch niemand gesprochen 😓

Es geht weniger darum den Quelltext schön zu machen, sondern die Vielzahl an Problemen die auftreten kann wenn man es nicht tut.

Beispiel:
  1. Packe ein GridPanel auf Frame A
  2. Stecke eine Komponente X in das Gridpanel, und gebe ihm z.B.
    Delphi-Quellcode:
    RowSpan = 2
  3. Platziere Frame A auf Formular B

Spätestens nach 5 Minuten ist die
Delphi-Quellcode:
RowSpan = 2
-Angabe rausgefallen. Das ist schon sichtbar wenn man das nächste mal das Projekt aufmacht und Formular B öffnet. Der Bug steckt schon seit Jahren in der VCL und sogar FMX.

Anderes Beispiel:
ImageLists. Die werden auch gerne redundant nochmal auf die Formulare kopiert. Wenn man nicht aufpasst hat man Grafiken dann doppelt und dreifach in die Anwendung eingelinkt.

Jumpy 29. Apr 2019 09:39

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Ich frag mal halb ketzerisch: Wenn man ein TFrame zur Designtime platziert. Hätte man nicht ein TPanel nehmen können?

bernau 29. Apr 2019 11:33

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von Jumpy (Beitrag 1431259)
Ich frag mal halb ketzerisch: Wenn man ein TFrame zur Designtime platziert. Hätte man nicht ein TPanel nehmen können?

???
meinst du das Frame zur Designzeit auf das Panel platzieren, oder das Frame zur Laufzeit erzeugen und dann auf das Panel platzieren?

Jumpy 29. Apr 2019 12:47

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Nee ich hatte bloß zu kurz gedacht:

Wenn ich ein Frame mit 2 Edits und einem Button drauf habe und das Frame zur Designtime auf ein Form (und dort ggf. auf ein Panel) lege, dann kann ich mir das Frame auch sparen und die 2 Edits und den Button auch direkt auf ein Panel legen.


Was ich damit natürlich nicht berücksichtigte ist z.B., dass man das Frame ja an verschiedenen Stellen (mehrfach) einsetzen kann und dann kan man das auch ruhig schon zur Designtime benutzen.

dummzeuch 29. Apr 2019 14:50

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von Jumpy (Beitrag 1431271)
Nee ich hatte bloß zu kurz gedacht:

Wenn ich ein Frame mit 2 Edits und einem Button drauf habe und das Frame zur Designtime auf ein Form (und dort ggf. auf ein Panel) lege, dann kann ich mir das Frame auch sparen und die 2 Edits und den Button auch direkt auf ein Panel legen.


Was ich damit natürlich nicht berücksichtigte ist z.B., dass man das Frame ja an verschiedenen Stellen (mehrfach) einsetzen kann und dann kan man das auch ruhig schon zur Designtime benutzen.

Nicht nur das, man kann in einem Frame auch Code hinterlegen, z.B. zur Eingabevalidierung.

dummzeuch 29. Apr 2019 14:53

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Vieleicht hilft es, wenn man statt eines Frames ein mittels ccpack erzeugtes Control verwendet?

https://blog.dummzeuch.de/delphi-cus...ntainers-pack/

Das unterstützt allerdings kein FMX und es sind wirklich Controls die man damit erzeugt, also keine Frames, d.h. Änderungen sind ein bisschen aufwändiger, weil man immer die Packages neu compilieren muss.

Uwe Raabe 29. Apr 2019 14:54

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von dummzeuch (Beitrag 1431284)
Nicht nur das, man kann in einem Frame auch Code hinterlegen, z.B. zur Eingabevalidierung.

... und auch Daten (z.B. lokale Felder, Konstanten) und verwendete Units kapseln.

Dennis07 30. Apr 2019 05:34

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Könntest per Designtime-Package die dortigen Controls oder direkt die ganzen Frames beispielsweise verstecken.
Das könnte dir helfen, habe ich mal vor Jahren geschrieben:

Delphi-Quellcode:
unit uDesignerSelectionProtector;

//////////////////////////////////////
///  Designer Selection Protector ///
///  ****************************  ///
///  (c) 2017 Dennis Göhlert a.o. ///
//////////////////////////////////////

interface

uses
  DesignIntf, DesignEditors,
  System.Classes,
  Vcl.Controls;

type
  TDesignerSelectionProtector = class(TSelectionEditor)
  private
    class procedure HideChildren(const ADesigner: IDesigner; const AControl: TWinControl); static;
    class procedure ViewChildren(const ADesigner: IDesigner; const AControl: TWinControl); static;
  private type
    TDesignerSelectionProc = procedure (const ADesigner: IDesigner; const AControl: TWinControl);

    TDesignerSelectionAction = record
      Verb: String;
      Proc: TDesignerSelectionProc;
    end;
  protected const
    FActions: array [0 .. 1] of TDesignerSelectionAction = (
      (
        Verb: 'Hide children';
        Proc: TDesignerSelectionProtector.HideChildren
      ), (
        Verb: 'View children';
        Proc: TDesignerSelectionProtector.ViewChildren
      )
    );
  public
    procedure ExecuteVerb(Index: Integer; const List: IDesignerSelections); override;
    function GetVerb(Index: Integer): String; override;
    function GetVerbCount: Integer; override;
  end;

  procedure Register;

implementation

procedure Register;
begin
  RegisterSelectionEditor(TWinControl, TDesignerSelectionProtector);
end;

{ TDesignerSelectionLocker }

procedure TDesignerSelectionProtector.ExecuteVerb(Index: Integer; const List: IDesignerSelections);
var
  LSelectionIndex: Integer;
  LSelection: TPersistent;
begin
  inherited;
  for LSelectionIndex := 0 to Pred(List.Count) do
  begin
    LSelection := List[LSelectionIndex];
    if LSelection is TWinControl then
    begin
      FActions[Index].Proc(Designer, LSelection as TWinControl);
    end;
  end;
  Designer.Modified;
end;

function TDesignerSelectionProtector.GetVerb(Index: Integer): String;
begin
  Result := FActions[Index].Verb;
end;

function TDesignerSelectionProtector.GetVerbCount: Integer;
begin
  Result := Length(FActions);
end;

class procedure TDesignerSelectionProtector.HideChildren(const ADesigner: IDesigner; const AControl: TWinControl);
var
  LIndex: Integer;
begin
  for LIndex := 0 to Pred(AControl.ControlCount) do
  begin
    AControl.Controls[LIndex].SetDesignVisible(False);
  end;
end;

class procedure TDesignerSelectionProtector.ViewChildren(const ADesigner: IDesigner; const AControl: TWinControl);
var
  LIndex: Integer;
begin
  for LIndex := 0 to Pred(AControl.ControlCount) do
  begin
    AControl.Controls[LIndex].SetDesignVisible(True);
  end;
end;

end.

dummzeuch 30. Apr 2019 08:49

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von Dennis07 (Beitrag 1431322)
Könntest per Designtime-Package die dortigen Controls oder direkt die ganzen Frames beispielsweise verstecken.
Das könnte dir helfen, habe ich mal vor Jahren geschrieben:

Delphi-Quellcode:
unit uDesignerSelectionProtector;

Hm, compiliert nicht:
* TDesignerSelectionProc muss als "of object" deklariert werden
EDIT: Nein, muss es nicht. Nur Delphi 2007 mag das so nicht. Delphi 10.3 compiliert ohne "of object".
* FActions muss als "array[0..1]" deklariert werden.

Aber Danke, das werde ich mir mal genauer ansehen.

dummzeuch 30. Apr 2019 09:28

AW: Änderungen im TFrame auf einem TForm verhindern.
 
OK, funktioniert, wenn auch etwas gewöhnungsbedürftig.

Ich überlege gerade, ob man mit einem IDesinger Interface nicht auch die Auswahl von Controls auf einem Frame verhindern kann. Müsste eigentlich gehen...

Auf jeden Fall mal Danke für diesen Startpunkt.

Uwe Raabe 30. Apr 2019 09:59

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von dummzeuch (Beitrag 1431334)
Ich überlege gerade, ob man mit einem IDesinger Interface nicht auch die Auswahl von Controls auf einem Frame verhindern kann. Müsste eigentlich gehen...

Die Auswahl der Controls will ich ja vielleicht gar nicht verhindern, sondern lediglich deren Änderung. In diesem Fall vermutlich sogar nur die Änderung von Position und Größe - also das, was bei Elemente fixieren passiert. Andere Änderungen mögen ja durchaus erlaubt sein.

Dennis07 30. Apr 2019 15:38

AW: Änderungen im TFrame auf einem TForm verhindern.
 
Zitat:

Zitat von dummzeuch (Beitrag 1431334)
OK, funktioniert, wenn auch etwas gewöhnungsbedürftig.

Ich überlege gerade, ob man mit einem IDesinger Interface nicht auch die Auswahl von Controls auf einem Frame verhindern kann. Müsste eigentlich gehen...

Auf jeden Fall mal Danke für diesen Startpunkt.

Deshalb war da das "..2" noch. Hatte es gestern versucht, aber nicht hinbekommen. Das geht nicht so einfach, wie man es sich denkt. Evtl kannst du es ja mal reinposten, wenn du eine Lösung hast.
Die Auswahl kannst du ja über
Delphi-Quellcode:
IDesignNotification.SelectionChanged
abfangen. Nur leider hängt sich die IDE dort immer auf, wenn du selbst eine änderung an der Auswahl vornimmst. Und das OBWOHL ich da Schutzmechanismen wie einen Lockcount eingeführt habe.
Wie gesagt, hab es gestern auf die Schnelle nicht mehr hinbekommen. Aber wäre dennoch an der Lösung interessiert.


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