2017-11-26 121 views
2

고정 너비가있는 동적으로 생성 된 체크 상자 및 라디오 버튼 (FMX가 아닌 VCL)을 포함하여 포함 된 텍스트를 기반으로 Heigth를 변경하고 싶습니다. 내 체크 박스와 라디오 버튼에 워드 랩을 사용할 수 있습니다. 그래서 TLabel이 AutoSize 및 WordWrap을 사용할 때와 같은 것을 얻고 싶습니다.Delphi FMX TCheckbox/TRadiobutton 자동 크기 조절

나는 이미이 가까이 얻을 관리했습니다 :

procedure TFMenu.Button1Click(Sender: TObject); 
var 
    ctr: Integer; 
    hostingComponent: TComponent; 
begin 
    hostingComponent := Form1; { in my case a Frame or Panel or sth. } 
    for ctr := 0 to pred(hostingComponent.ComponentCount) do 
    begin 
    if hostingComponent.Components[ctr] is TRadioButton { or TCheckBox } then 
    begin 
     with (hostingComponent.Components[ctr] as TRadioButton) do 
     begin 
     Height := 0; { if text or text Width changes this is useful } 
     while (Height) * (Width - 32) 
     <= 
     (Canvas.TextHeight(Text) * 1.25) * Canvas.TextWidth(Text) do 
     begin 
      Height := Height + 1; 
     end; 
     end; 
    end; 
    end; 
end; 

이, 20 개 및 150 문자 사이의 텍스트를 허용 같은 뭔가를 작동 그러나 나는 이것이 매우 잘못 알고 나도 몰라 , 내가 여기서 누락 된 것. Canvas.TextHeight1.25을 곱하면 위에서 언급 한 길이만큼 텍스트가 잘 보이지만 그 이유는 알 수 없습니다. Width - 32은 체크 상자/라디오 버튼 이미지의 크기 때문입니다. 처리 할 텍스트가 아닙니다.

그래서 내 질문이 포함 된 텍스트를 기반으로하는 구성 요소 의 Heigth을 변경하는 방법 이다 (I 잘 될 것 (32)를 추측, 그것은 현실에서 다를 수있다).

기타 : 코드가 예상대로 작동하도록 변경하려면 어떻게해야합니까? 그 뒤에있는 수학 (추측 된 값 1.25에 의한 곱셈 제외)은 정확해야하지만 사용하는 영역은 Checkbox/Radiobutton의 영역이 텍스트를 완전히 포함하지는 않지만 일부 여유 공간이 텍스트 블록이 아니며 간단히 왼쪽으로 묶여 있습니다. 그러나 이것이 중요하거나 어떻게 다루는 지 확실하지 않습니다.

답변

3

Canvas.MeasureText() 메서드를 사용하여 텍스트를 측정 한 다음 TRadioButton의 크기를 설정할 수 있습니다. 예를 들어

:

procedure TForm22.Button1Click(Sender: TObject); 
var 
    r: TRectF; 
begin 
    rb1:= TRadioButton.Create(self); 
    rb1.Parent := self; 
    rb1.Position.X := 100; 
    rb1.Position.Y := 8; 
    rb1.Size.Height := 17; 
    rb1.Size.Width := 260; 

    rb1.StyledSettings := []; 
    rb1.TextSettings.Font.Size := 18; 
    rb1.TextSettings.WordWrap := True; 
    rb1.Canvas.Font.Size := rb1.TextSettings.Font.Size; 

    r := RectF(0, 0, rb1.Size.Width-24, 10000); 
    rb1.Canvas.MeasureText(r, s, True, [], TTextAlign.Leading, TTextAlign.Leading); 

    rb1.Size.Height := r.Bottom; 
    rb1.Text := s; 
end; 

ARect (VAR) 매개 변수는 텍스트의 경계 사각형을 지정한다. 이 함수는 가능한 경우 사각형 내부의 텍스트를 맞 춥니 다. 너비 제한을 지정하지만 높이가 충분히 큰 경우 함수는 너비를 따르고 필요한 높이를 측정합니다 (반환 된 TRectF에서 수정 됨).

예에서 실제 라디오 버튼을 보상하기 위해 너비는 TRadioButton에서 24를 뺍니다. 기본 스타일 데이터가 21이면 충분하지만 3을 계산에 안전한쪽에 추가했습니다. 다른 스타일에서는이 숫자가 다를 수 있습니다. TRadioButton/TCheckBox의 스타일 데이터에 text 구성원의 Position.X 속성을 참조하십시오.

내 코드 예제에서 알 수 있듯이, 사용했던 1.25 요소로 아무 것도 조정할 필요가 없습니다. 내 시스템이 100 % DPI이고, 125 % 인 경우 경험 한 것을 설명 할 수 있습니다. 그래도 문제가 해결되지 않으면 프로그램이 실행중인 시스템을 확인하고 필요에 따라 보충해야합니다.

마지막으로 width = 260 및 width = 400의 두 라디오 버튼이있는 양식의 그림.

enter image description here

+0

대단히 감사합니다. 이것은 나를 위해 작동합니다. 관심 분야 : 원래 RadioButton 이미지의 너비가 24임을 어떻게 알았습니까? DPI가 100 %입니다. Heigth가 너무 낮고 1 인 것을 보았을 때 요인 1.25는 추측 된 숫자였습니다.25는 Heigth가 라디오 버튼이 포함 된 더 많은 텍스트가되었지만, 실제로는 그것을 해결하지는 않았지만, 원하는 출력에 가까워졌습니다. 그래서 큰 텍스트의 경우 라디오 버튼은 텍스트의 크기를, 텍스트의 경우에는 라디오 버튼 만 3 문자로합니다 단지 몇 픽셀 높았습니다. 그러나 귀하의 솔루션이 문제를 성공적으로 해결 했으므로 해당 정보는 적합하지 않습니다. – qGold

+0

안녕하십니까. * 당신은 어떻게 알았습니까? * TRadioButton/TCheckBox에 대한 스타일 데이터에서 볼 수 있습니다. 텍스트 멤버의 Position.X 속성은 21입니다. 계산시 안전면에 3을 더했습니다. . 사용 된 스타일이 기본값과 다른 경우 이러한 측정 값이 다를 수 있으므로 질문에 대한 답을 편집했습니다. –

+0

감사합니다. 내가 폭을 어떻게 찾았는지 물어 본 이유는 내 앱이 다른 폭풍우에서 돌아가고 사용자가 크기를 약간 다르게 할 수있는 설정을 할 수 있기 때문에 런타임에 이상적으로 가져와야합니다. 귀하의 대답은이를 충당하는 것 같습니다. 내가 약간의 잘못을 저지른다면 알려 드리겠습니다. – qGold