Ir al contenido


Foto

propiedad AutoSize


  • Por favor identifícate para responder
6 respuestas en este tema

#1 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 832 mensajes
  • LocationMisiones, Argentina

Escrito 12 febrero 2015 - 12:31

Al crear un control de tipo TPanel y asignarle un valor a sus propiedades más importantes (Top, Left, Caption, etc.) No logro hacer que la propiedad AutoSize funcione.
¿Alguien conoce la manera de hacer que un TPanel creado en tiempo de ejecución se autoajuste a la dimensión de su Caption?

Gracias,  :cheesy:
Saludos

  • 0

#2 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 13 febrero 2015 - 03:36

Suponiendo que el form ("self" en el código) tenga puesto el mismo font que el panel, sería así:



delphi
  1. Panel1.Width:= self.Canvas.TextExtent(Panel1.Caption).cx + 20;



Si no usan el mismo font, tienes primero que copiarlo antes de medir la longitud del caption:



delphi
  1. Self.Font.Name:=  Panel1.Font.Name;
  2. Self.Font.Size:=  Panel1.Font.Size;
  3. Self.Font.Style:= Panel1.Font.Style;
  4. Panel1.Width:= self.Canvas.TextExtent(Panel1.Caption).cx + 20;



El +20 es por dejar un poco de margen solamente.
  • 0

#3 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 13 febrero 2015 - 07:39

Este ejemplo te muestra el Panel a la dimensión de su caption si no tiene controles dentro, en caso contrario se ajusta a sus controles:


delphi
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, ExtCtrls, StdCtrls;
  8.  
  9. type
  10.   TPanel = class(ExtCtrls.TPanel)
  11.   protected
  12.     function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override;
  13.   end;
  14.  
  15.   TForm1 = class(TForm)
  16.     Panel1: TPanel;
  17.     Button1: TButton;
  18.     procedure Button1Click(Sender: TObject);
  19.   private
  20.     { Private declarations }
  21.   public
  22.     { Public declarations }
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.dfm}
  31.  
  32. function TPanel.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean;
  33. var
  34.   S: TSize;
  35. begin
  36.   Result:= inherited CanAutoSize(NewWidth, NewHeight);
  37.   S:= Canvas.TextExtent(Caption);
  38.   if NewWidth < S.cx then NewWidth:= S.cx + (BorderWidth+BevelWidth)*2 + 2;
  39.   if NewHeight< S.cy then NewHeight:= S.cy + (BorderWidth+BevelWidth)*2;
  40. end;
  41.  
  42. procedure TForm1.Button1Click(Sender: TObject);
  43. begin
  44.   Panel1.AutoSize:= true;
  45. end;
  46.  
  47. end.




Saludos.
  • 0

#4 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 832 mensajes
  • LocationMisiones, Argentina

Escrito 13 febrero 2015 - 12:41

Gracias a los dos genios (@Sergio y @escafandra).  (y)
Aunque parezca mentira, no sabía (o quizá no recordaba, pues mi cabeza anda como puede) de la existenncia de TextExtent. Cuando busqué GetTextExtent, me dio dolor de cabezas, meterme con las funciones de la API. Por lo que decidí pedir ayuda.
TextExtent era la función que buscaba. Con eso está resuelto.
Comento que es para agregar paneles con pedazos de texto separados que se irán incorporando al momento que se los escribe.
El asunto de las tipografías puede resultar un problema, pero esa función supongo que trabaja "sobre" GetTextExtent y tendrá en cuenta el contexto de dispositivo de ese panel y por ende la tipografía del mismo, etc.  ;)

El +20 es por dejar un poco de margen solamente.

Supongo que funcionará la propiedad Align, pienso usarla con alLeft y márgenes.

Ahora tengo que adecuarlo a la creación dinámica de TPanels, que irán dentro de un arreglo dinámico (valga la redundancia).

Saludos.
(b)
  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 13 febrero 2015 - 01:18

esa función supongo que trabaja "sobre" GetTextExtent y tendrá en cuenta el contexto de dispositivo de ese panel y por ende la tipografía del mismo, etc.

Funciona en el contexto del Canvas que la llama, incluido su tipo de fuente ya definido en él. En este caso debes usar el Canvas del TPanel.
Aquí ya se habló del tema y de su uso alternativo con la API.

Ahora tengo que adecuarlo a la creación dinámica de TPanels, que irán dentro de un arreglo dinámico

El ejemplo que puse es una clase derivada que sustituye a la original TPanel en la unit donde la uses. También probé creando dináminamente TPanels.

Saludos.
  • 0

#6 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 832 mensajes
  • LocationMisiones, Argentina

Escrito 16 febrero 2015 - 02:12

Supongo que el tema está resuelto, pero para que quede en este hilo lo quiero comentar.
Mi problema surgió al intentar asignar la propiedad Autosize en un TPanel creado dentro de otro TPanel o TForm. Pero en realidad, la propiedad autosize no era el problema y es lo que quiero aclarar.
Al darle un valor a la propiedad Width, el panel quedaba con un tamaño mínimo y no me servía, por lo que se me ocurrió ponerle la propiedad AutoSize en True, luego de asignarle valores a Caption, etc. ... y nada.
También necesitaba que se ajusten a la izquierda, por lo que había dejando en Align en alLeft, esto me facilitaría las cosas al tener que darle valores a las coordenadas y no tendría que recurrir a otras funciones, pero no funcionó.

El asunto es que al cambiar la propiedad Align antes que los demás valores, los valores Width y Height, al parecer, son ignorados y el control aparece con una dimensión mínima y regular.
Al cambiar de lugar la asignación del valor de Align todo se solucionó y gracias a la ayuda que me brindaron, tan solo usando TextExtent pude redimensionar al panel y ajustarlo a la izquierda, sin tener que crear otra clase, o algo por el estilo.

El código tiene nombres extraños que fueron definidos en el Form, pero sirve como ejemplo de como quedó:  ;)



delphi
  1. procedure TfrmCajaReg.ActualizarInfoEntrada;
  2. var
  3.   I, N: Integer;
  4. begin
  5.   N:= ListaCadBusq.Count;
  6.   case TE of
  7.     Busq:
  8.       begin
  9.         I:= 0;
  10.         SetLength(panArr, N * SizeOf(TPanel));
  11.         while I < N do
  12.         begin
  13.           panArr[I]:= TPanel.Create(Self);
  14.           with panArr[I] do
  15.           begin
  16.             Caption:= ListaCadBusq.Strings[N-I-1];
  17.             Parent:= panAjusteInfoText;
  18.             Width:= Canvas.TextExtent(ListaCadBusq.Strings[N-I-1]).cx + 10;
  19.             Align:= alLeft;  // Esta línea antes figuraba al principio
  20.             Alignment:= taCenter;
  21.           end;
  22.           I:= I+1;
  23.         end;
  24.       end;
  25.   end;
  26. end;



Bueno, luego procedo a un Free desde el último hasta el primero de los elementos, la dimensión del arreglo no importa, pues es pequeña y siempre la redimensiona a la entrada del procedimiento, aun así esto está en oceso de creación no de depuración.

Dado que existen dos eventos uno OnResize y otro OnConstrainedResize, y que el segundo se llama después de OnCanResize, supongo que es OnConstrainedResize el que se ejecuta restringiendo el redimensionamiento cuando la propiedad Align está en True, por esta razón al ponerlo al final, no hay problema y todo funciona bien. Pero es solo una suposición ^o|

Saludos
(b)
  • 0

#7 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 16 febrero 2015 - 02:31

Me alegra de que tengas resuelto tu problema, quizás deberías marcar el tema como [Resuelto]
(b)

Saludos.
  • 0




IP.Board spam blocked by CleanTalk.