[Erledigt] Ausrichten von Controls an Textlänge

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

[Erledigt] Ausrichten von Controls an Textlänge

Beitrag von Michl »

Hallo,

ich habe das Problem, dass sich die Beschriftungen auf einem Formular ändern können (bei z.B. einer anderen Sprache). Dabei kann es passieren, dass ein anderes Control die längste Beschriftung erhält.

Nun möchte ich gern links neben TEdits TLabels stehen haben, wobei diese immer linksbündig untereinander angeordnet stehen sollen. Kann man dieses Verhalten ohne Code steuern oder muss ich die Längen der jeweiligen Captions ermitteln und dann die TEdits entsprechend an der längsten Beschriftung anordnen?

Ich könnte die TLabels auch auf ein anderes Parentcontrol (TPanel, TGroupbox) anordnen, dann kann ich diese aber nicht mehr per Anchors an den TEdits in der Höhe ausrichten. TLabeledEdit zeigt ein noch schwieriger zu steuerndes Verhalten. Auch hier konnte ich nicht den entscheidenden Hinweis entdecken: http://wiki.lazarus.freepascal.org/Autosize_/_Layout

Beispiel, wie ich es meine anbei.

Vielen Dank für dienliche Hinweise

Michael
Dateianhänge
TestAnordnen.zip
(2.08 KiB) 37-mal heruntergeladen
Zuletzt geändert von Michl am Di 17. Nov 2015, 16:44, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Warf
Beiträge: 2121
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Ausrichten von Controls an Textlänge

Beitrag von Warf »

Die meiner Meinung nach beste Lösung ist zwar relativ dreckig, bietet aber ein vernünftiges Resultat:

Code: Alles auswählen

funtion GetControlWidth(Cap: String; F: TFont; P: TWinControl): Integer;
begin
  With TLabel.Create(self) do
  try
    Parent := P;
    Font := F;
    Caption := Cap;
    AutoSize := True;
    Result := Width + 5; // 5 Als Offset
  finally
    Free;
  end;
end;
Das sollte so funktionieren (habe es aus dem Kopf geschrieben, nicht getestet)

Aufruf wäre dann so:

Code: Alles auswählen

Edit1.Width := GetControlLen(LongestText, Edit1.Font, Self);

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Ausrichten von Controls an Textlänge

Beitrag von Michl »

Danke für die Anwort. Leider ist das nicht ganz meine Frage. Meine Frage ist eher dahingehend, ob man das mit Childsizing etc. irgenwie hin bekommt. Per Code würde ich das so lösen:

Code: Alles auswählen

procedure TForm1.LabelTextChanged;
var
  aComponent: TComponent;
  DefComponent: TComponent;
  i: Integer;
begin
  DefComponent := nil;
  for i := 0 to ComponentCount - 1 do begin
    aComponent := Components[i];
    if Assigned(aComponent) and
       (aComponent is TLabel) and
       (not Assigned(DefComponent) or
       (TLabel(DefComponent).Canvas.TextWidth(TLabel(DefComponent).Caption) <
        TLabel(aComponent).Canvas.TextWidth(TLabel(aComponent).Caption)))
    then DefComponent := aComponent;
  end;
  if Assigned(DefComponent) then Edit1.AnchorSide[akLeft].Control := TControl(DefComponent);
end; 
Bsp. anbei.

Allerdings würde mich interessieren, ob dies nicht irgenwie per Objektinspektor zu lösen ist?
Dateianhänge
AnordnenPerCode.zip
(2.29 KiB) 31-mal heruntergeladen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: [Erledigt] Ausrichten von Controls an Textlänge

Beitrag von Michl »

Aus dem Schweigen schlussfolgere ich, dass das wohl zur Zeit per IDE nicht möglich ist.

Als Lösung, habe ich mir eine Funktion geschrieben, nach der ich bei der Initialisierung des Formulars das oberste TEdit per Anchors ausrichte (alle darunter liegenden TEdits richten sich dann automatisch am obersten TEdit aus):

Code: Alles auswählen

function LongestLabel(Labels: array of TLabel): TControl; 
var
  aLabel: TLabel;
  aWidth, ResultWidth: Integer;
begin
  Result := nil;
  ResultWidth := -1;
  for aLabel in Labels do
    if Assigned(aLabel) then begin
      aWidth := aLabel.Canvas.TextWidth(aLabel.Caption);
      if not Assigned(Result) or (aWidth > ResultWidth) then begin
        ResultWidth := aWidth;
        Result := aLabel;
      end;
    end;
end;   
Für mich ist die Lösung ausreichend. Danke trotzdem fürs Mitdenken!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten