Pues eso… que lo que publiqué anteayer sobre ajustar automáticamente la fuente de un formulario según la configuración del sistema (Cambiar automáticamente las fuentes de nuestro formulario a las de Windows), estaba muy bien, pero no era lo que yo andaba buscando… yo lo que quería era que los controles también cambiaran.
La batallita del Guille
Y me puse a ello… como soy un poquillo torpe, ya sabes, no tengo estudios informáticos ni de otros tipos, pues… empecé a escribir el código para cambiar cada uno de los controles del formulario, y por supuesto también el del formulario, ahí si llego ;-). Sí, lo hice, escribí todo el código, con métodos recursivos, etc. En fin… :-/
La cuestión es que pensé que también estaría guay (cool) poder cambiar las fuentes, así todo estaría más grande… o más pequeño, ya que en el formulario de prueba (ver figura 1) puse la opción de ampliar o reducir.
Pero aquello era un caos, cuando ampliaba, lo hacía según el ancho y el alto y claro, si los controles no tienen todos los Anchor necesarios, pues… se te quedaba espacio vacío por aquí y por allá… no tengo capturas (¡gracias a Dios! si no, ya no vendrás más a visitarme 😛 )
Con decirte que hice hasta una clase para que manejase el tema este del cambio de los controles y así hacerlo más cool… con un evento que indicaba que se estaban haciendo los cambios, etc.; sí, lo que yo te diga, en fin…
Bueno, vale… otro día hago la captura y así ves cómo se puede uno embrollar con lo que después resultó ser algo muy simple de codificar.
La solución (muy fácil y sencilla)
Pues eso, la solución, para esto de que se cambien los controles de tamaño según indiquemos, es muy simple, tanto que… bueno… mejor me callo… ¡ay zeñó!
Y todo surgió porque los controles quedaban muy mal al cambiar el tamaño, y me dio por probar (esto aún podría estar en la batallita del Guille, pero bueno…) quitando el cambio del tamaño del formulario y de los controles, y dejar solo el cambio del tamaño de la fuente y… ¡voilà, todo va a la perfección!. No sabes la de cabezazos que me hubiera dado contra la pared… menos mal que ahora me he pelado al 2 y no era plan… 🙂
Te muestro un par de capturas con el 25% de ampliación y el 50% para que te hagas una idea de lo bien que funciona 🙂 y después te muestro el código tanto para Visual Basic como para C#.
Nota:
Según parece, la imagen 1 y 2 son iguales, pero si te fijas en la figura 3, en la que muestro el IDE de Visual Studio, comprobarás que el tamaño del formulario es significativamente más grande que el mostrado en el diseñador de VS.
Pulsa en las imágenes para verlas en grande.
El código para cambiar el tamaño de los controles de un formulario
Comentarte que todo está en cambiar el tamaño de la fuente del formulario, por tanto debes tener asignado el valor Font a la propiedad AutoScaleMode del formulario (es el valor predeterminado al crear un nuevo formulario).
El código para Visual Basic
'--------------------------------------------------------------------------
' Métodos para cambiar el tamaño del formulario
' y de sus controles
'--------------------------------------------------------------------------
''' <summary>
''' Cambia el tamaño del formulario (o control) indicado,
''' ampliando o reduciendo según un porcentaje.
''' Recomendado es solo cambiar el formulario.
''' </summary>
Private Sub cambia(ctr As Control, ampliar As Boolean, por As Integer)
If ampliar = False Then
por = -por
End If
'----------------------------------------------------------------------
' El ancho y alto es mejor no cambiarlo,
' las proporciones de los controles se verán bien
' pero si el Anchor no está "pensado" para todos
' los controles, quedarán espacios vacíos con
' respecto al diseño original.
' Al cambiar la fuente del formulario,
' el aspecto original no se pierde.
'----------------------------------------------------------------------
'----------------------------------------------------------------------
' Al cambiar el tamaño de la fuente del formulario
' los controles se adaptan al nuevo tamaño de fuente,
' sin perder el aspecto del diseño original.
'
' El formulario debe tener asignada la propiedad
' AutoScaleMode = Font
'----------------------------------------------------------------------
'
' Se debería poner un máximo y mínimo a las fuentes
'
Dim fntSize = ctr.Font.Size
fntSize = calculaPorcentaje(fntSize, por)
' No admitir valores menores de uno
' ni valores mayores de 3 veces la fuente
If fntSize < 1 OrElse fntSize > ctr.Font.Size * 3 Then
fntSize = ctr.Font.Size
End If
ctr.Font = New Font(ctr.Font.FontFamily,
fntSize, ctr.Font.Style,
ctr.Font.Unit, ctr.Font.GdiCharSet,
ctr.Font.GdiVerticalFont)
End Sub
''' <summary>
''' Calcula el porcentaje a partir de un valor Single,
''' para el tamaño de la fuente.
''' </summary>
Private Function calculaPorcentaje(valor As Single, porcentaje As Integer) As Single
Return valor + (valor * porcentaje / 100)
End Function
El código para C#
// --------------------------------------------------------------------------
// Métodos para cambiar el tamaño del formulario
// y de sus controles
// --------------------------------------------------------------------------
/// <summary>
/// Cambia el tamaño del formulario (o control) indicado,
/// ampliando o reduciendo según un porcentaje.
/// Recomendado es solo cambiar el formulario.
/// </summary>
private void cambia(Control ctr, bool ampliar, int por)
{
if (ampliar == false)
por = -por;
// ----------------------------------------------------------------------
// El ancho y alto es mejor no cambiarlo,
// las proporciones de los controles se verán bien
// pero si el Anchor no está "pensado" para todos
// los controles, quedarán espacios vacíos con
// respecto al diseño original.
// Al cambiar la fuente del formulario,
// el aspecto original no se pierde.
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// Al cambiar el tamaño de la fuente del formulario
// los controles se adaptan al nuevo tamaño de fuente,
// sin perder el aspecto del diseño original.
//
// El formulario debe tener asignada la propiedad
// AutoScaleMode = Font
// ----------------------------------------------------------------------
//
// Se debería poner un máximo y mínimo a las fuentes
//
var fntSize = ctr.Font.Size;
fntSize = calculaPorcentaje(fntSize, por);
// No admitir valores menores de uno
// ni valores mayores de 3 veces la fuente
if (fntSize < 1 || fntSize > ctr.Font.Size * 3)
fntSize = ctr.Font.Size;
ctr.Font = new Font(ctr.Font.FontFamily, fntSize,
ctr.Font.Style, ctr.Font.Unit,
ctr.Font.GdiCharSet, ctr.Font.GdiVerticalFont);
}
/// <summary>
/// Calcula el porcentaje a partir de un valor Single,
/// para el tamaño de la fuente.
/// </summary>
private float calculaPorcentaje(float valor, int porcentaje)
{
return valor + (valor * porcentaje / 100);
}
Al método cambia le pasamos el control o formulario (recomendable el formulario) en el que queremos hacer el cambio de tamaño, el valor de ampliar es si queremos ampliar (true) o reducir (false) y por es el porcentaje, que es un valor entero y puede ser 0 (cero) para no hacer nada o dejarlo como estaba, o cualquier otro tamaño (no te recomiendo un valor mayor de 175 si no, pues… te faltará pantalla… 🙂
Como puedes comprobar, he puesto una comprobación para que el tamaño de la fuente no sea menor de 1 ni mayor de 3 veces el tamaño inicial.
Si quieres cambiarlo, hazlo, pero al menos deja la comprobación de que no sea menor de uno (o cero) ya que so es cero (0) te dará error.
Y ahora pasemos al código que he usado para cambiar el tamaño del formulario y sus controles.
El código de ejemplo para cambiar el tamaño según un porcentaje
En el ejemplo que he hecho (ver cualquiera de las figuras) he puesto la opción de Ampliar o Reducir, un combo con los porcentajes a usar y el botón Cambiar para aplicar el cambio.
También he puesto un botón para restaurar el tamaño al inicial (Restablecer fuente) pero en realidad no es necesario, ya que al indicar 0% se deja todo como estaba al inicio.
Lo que si hago es que ese porcentaje sea fijo, es decir, siempre que pulses en, por ejemplo, 50% se cambiará al 50% del valor inicial.
Te aclaro esto porque inicialmente (ya sabes: la torpeza del Guille) ese porcentaje lo aplicaba al valor que ya hubiese de antes, por tanto, si inicialmente lo habías ampliado al 10% y después seleccionabas el 50% este último se aplicaba sobre la ampliación (o reducción) anterior, y… bueno, que no quedaba nada bien.
Para conseguir esto, que siempre se aplique el porcentaje según la fuente inicial, he creado una variable llamada miWinFont, esa es la fuente que tiene el sistema, ya que he usado el mismo código que te mostré en el artículo anterior (Cambiar automáticamente las fuentes de nuestro formulario a las de Windows) para utilizar la fuente indicada en Windows.
La asignación de esa variable se hace al inicio del programa (en el constructor) y después se usa para reiniciar el tamaño de la fuente antes de hacer el cambio, ahora lo verás en el código.
Como tip te puedo decir que puedes usar otra forma de hacerlo, por ejemplo usando el valor de fntSize a partir del valor de miWinFont en vez de la fuente del formulario, pero no he cambiado el código porque eso se me acaba de ocurrir mientras escribo el artículo, y ya no es plan de cambiar el código 😉
Vamos a lo que vamos.
Empecemos con el código de Visual Basic, pero tanto en el de VB como en el de C# lo que hago es lo mismo: hacer el cambio usando el evento Click del botón Cambiar.
El código para Visual Basic de los métodos de evento
'
' Los métodos de evento para el cambio de la fuente
'
Private Sub btnCambiarTamaño_Click(sender As Object, e As EventArgs) Handles _
btnCambiarTamaño.Click
' Cambiar solo el tamaño de la fuente del formulario
txtInfo.Text = "Cambiando el tamaño de los controles..."
Application.DoEvents()
Me.Hide()
' restablecer a la fuente inicial
Me.Font = miWinFont
' hacer el cambio de tamaño
cambia(Me, optAmpliar.Checked, CInt(cboTamaños.SelectedItem))
Me.Show()
txtInfo.Text = "Cambiado el tamaño de los controles."
Application.DoEvents()
End Sub
Private Sub btnRestablecerFuente_Click(sender As Object, e As EventArgs) Handles _
btnRestablecerFuente.Click
' Restablecer siempre a la fuente del sistema
' si no queremos usar la del sistema,
' asignar al valor de miFuente (la original al diseñar)
Me.Font = miWinFont
End Sub
Ahora después te muestro dónde declaro miWinFont y dónde la asigno.
El código para C# de los métodos de evento
//
// Los métodos de evento para el cambio de la fuente
//
private void btnCambiarTamaño_Click(object sender, EventArgs e)
{
// Cambiar solo el tamaño de la fuente del formulario
txtInfo.Text = "Cambiando el tamaño de los controles...";
Application.DoEvents();
this.Hide();
// restablecer a la fuente inicial
this.Font = miWinFont;
// hacer el cambio de tamaño
cambia(this, optAmpliar.Checked, Convert.ToInt32(cboTamaños.SelectedItem));
this.Show();
txtInfo.Text = "Cambiado el tamaño de los controles.";
Application.DoEvents();
}
private void btnRestablecerFuente_Click(object sender, EventArgs e)
{
// Restablecer siempre a la fuente del sistema
// si no queremos usar la del sistema,
// asignar al valor de miFuente (la original al diseñar)
this.Font = miWinFont;
}
Este es el código donde se define y se asigna miWinFont.
Adivina cuál es el de VB y cuál el de C# 😉
Public Class Form1
''' <summary>
''' La fuente del sistema
''' </summary>
Private miWinFont As Font
[...]
'
' El constructor del formulario
'
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
miFont = Me.Font
Me.Font = SystemFonts.IconTitleFont
AddHandler SystemEvents.UserPreferenceChanged,
AddressOf SystemEvents_UserPreferenceChanged
miWinFont = Me.Font
infoFuentes()
End Sub
'
' Los métodos de evento para interactuar con la configuración de Windows
'
Private Sub SystemEvents_UserPreferenceChanged(ByVal sender As Object,
ByVal e As UserPreferenceChangedEventArgs)
If e.Category = UserPreferenceCategory.Window Then
Me.Font = SystemFonts.IconTitleFont
miWinFont = Me.Font
End If
mostrarInfoForm()
txtInfo.Text = String.Format("UserPreferenceChanged.Category = {0} ({1:HH:mm:ss}){2}{3}",
e.Category.ToString(), Date.Now,
Microsoft.VisualBasic.vbCrLf,
txtInfo.Text)
End Sub
public partial class Form1 : Form
{
/// <summary>
/// La fuente del sistema
/// </summary>
private Font miWinFont;
[...]
//
// El constructor del formulario
//
public Form1()
{
// This call is required by the designer.
InitializeComponent();
// Add any initialization after the InitializeComponent() call.
miFont = this.Font;
this.Font = SystemFonts.IconTitleFont;
SystemEvents.UserPreferenceChanged +=
SystemEvents_UserPreferenceChanged;
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
// Para que tenga dos m\f2étodos de evento el evento Load
this.Load += new System.EventHandler(this.Form1_Load);
miWinFont = this.Font;
infoFuentes();
}
//
// Los métodos de evento para interactuar con la configuración de Windows
//
private void SystemEvents_UserPreferenceChanged(object sender,
UserPreferenceChangedEventArgs e)
{
if (e.Category == UserPreferenceCategory.Window) {
this.Font = SystemFonts.IconTitleFont;
miWinFont = this.Font;
}
mostrarInfoForm();
txtInfo.Text = string.Format("UserPreferenceChanged.Category = {0}"+
"({1:HH:mm:ss}){2}{3}",
e.Category.ToString(), DateTime.Now,
"\r\n", txtInfo.Text);
}
Nota:
No te preocupes por la definición de los métodos infoFuentes ni mostrarInfoForm, ese código está en el ZIP que te pondré al final con el código completo.
Y esto es todo… ya ves qué simple… 🙂
Espero que te sea de utilidad, ¡’esa es siempre la idea!
Nos vemos.
Guillermo.
P.S.
Comentarte que en el código completo (sí, para VB y C#) la aplicación lo que hace es permitir que selecciones un fichero (archivo) y te muestre las propiedades, nombre completo, directorio, fecha de creación, etc.
El código completo del ejemplo (solución para Visual Studio usando .NET 4.7.2)
El ZIP con el código completo (una solución de Visual Studio 2017 con los proyectos de Visual Basic y C#
ZIP: Cambiar tamaño controles.zip (254 KB)
MD5 Checksum: 0B5DDD8A525D61647F10070EFC198DCA
P.S. 2 (31/Dic/18)
Aquí tienes un ejemplo de cómo hacer que el resto de formularios de nuestra aplicación utilicen el tamaño asignado en el formulario principal:
Interceptar el cambio del tamaño de los controles de un formulario en otros formularios de la aplicación.