propiedad AutoSize
Comenzado por
cram
, feb 12 2015 12:31
6 respuestas en este tema
#1
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,
Saludos
¿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,
Saludos
#2
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í:
Si no usan el mismo font, tienes primero que copiarlo antes de medir la longitud del caption:
El +20 es por dejar un poco de margen solamente.
delphi
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
Self.Font.Name:= Panel1.Font.Name; Self.Font.Size:= Panel1.Font.Size; Self.Font.Style:= Panel1.Font.Style; Panel1.Width:= self.Canvas.TextExtent(Panel1.Caption).cx + 20;
El +20 es por dejar un poco de margen solamente.
#3
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:
Saludos.
delphi
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TPanel = class(ExtCtrls.TPanel) protected function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override; end; TForm1 = class(TForm) Panel1: TPanel; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} function TPanel.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; var S: TSize; begin Result:= inherited CanAutoSize(NewWidth, NewHeight); S:= Canvas.TextExtent(Caption); if NewWidth < S.cx then NewWidth:= S.cx + (BorderWidth+BevelWidth)*2 + 2; if NewHeight< S.cy then NewHeight:= S.cy + (BorderWidth+BevelWidth)*2; end; procedure TForm1.Button1Click(Sender: TObject); begin Panel1.AutoSize:= true; end; end.
Saludos.
#4
Escrito 13 febrero 2015 - 12:41
Gracias a los dos genios (@Sergio y @escafandra).
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.
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.
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.
Supongo que funcionará la propiedad Align, pienso usarla con alLeft y márgenes.El +20 es por dejar un poco de margen solamente.
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.
#5
Escrito 13 febrero 2015 - 01:18
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.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.
Aquí ya se habló del tema y de su uso alternativo con la API.
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.Ahora tengo que adecuarlo a la creación dinámica de TPanels, que irán dentro de un arreglo dinámico
Saludos.
#6
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ó:
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
Saludos
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
procedure TfrmCajaReg.ActualizarInfoEntrada; var I, N: Integer; begin N:= ListaCadBusq.Count; case TE of Busq: begin I:= 0; SetLength(panArr, N * SizeOf(TPanel)); while I < N do begin panArr[I]:= TPanel.Create(Self); with panArr[I] do begin Caption:= ListaCadBusq.Strings[N-I-1]; Parent:= panAjusteInfoText; Width:= Canvas.TextExtent(ListaCadBusq.Strings[N-I-1]).cx + 10; Align:= alLeft; // Esta línea antes figuraba al principio Alignment:= taCenter; end; I:= I+1; end; end; end; 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
Saludos
#7
Escrito 16 febrero 2015 - 02:31
Me alegra de que tengas resuelto tu problema, quizás deberías marcar el tema como [Resuelto]
Saludos.
Saludos.