el Guille, la Web del Visual Basic, C#, .NET y más...

Interceptar el cambio del tamaño de los controles de un formulario en otros formularios de la aplicación

 
Publicado el 31/Dic/2018
Actualizado el 31/Dic/2018
Autor: Guillermo 'guille' Som

Esta sería la versión 2.0 del artículo que publiqué hace un par de días: Cambiar el tamaño de los controles de un formulario automáticamente, en esta ocasión lo que te voy a enseñar es cómo interceptar en los restantes formularios de la aplicación esos cambios y actuar consecuentemente, es decir, que también cambie el tamaño de sus controles. Y todo esto aunque el resto de formularios ya estén abiertos. (publicado en mi blog)




 

Este contenido está obtenido de mi blog, la URL original es:
Interceptar el cambio del tamaño de los controles de un formulario en otros formularios de la aplicación

Esta sería la versión 2.0 del artículo que publiqué hace un par de días: Cambiar el tamaño de los controles de un formulario automáticamente, en esta ocasión lo que te voy a enseñar es cómo interceptar en los restantes formularios de la aplicación esos cambios y actuar consecuentemente, es decir, que también cambie el tamaño de sus controles. Y todo esto aunque el resto de formularios ya estén abiertos.

Nota:
Por si no te lo dije en el artículo anterior (es que es muy largo y me da pereza tener que leerlo al completo 🙂 ), para que los controles cambien de tamaño, el tipo de fuente debe ser la predeterminada, si usas una fuente definida de forma explícita, ese control no cambiará, salvo que hayas definido la propiedad Anchor.

En este segundo artículo lo comprobarás en uno de los controles, en el que el tamaño de la fuente está asignado de forma explícita.

Lo que hay que hacer para que esto funcione es definir un evento en el formulario principal (en el ejemplo que te mostraré aquí dicho formulario se llama Form1. Por tanto, si tu formulario principal se llama de otra forma, cambia Form1 por el nombre de tu formulario principal.

En Visual Basic se crea de forma predeterminada una colección con todos los formularios que tenemos en nuestro proyecto y no es necesario instanciarlos para acceder a ellos; pero como eso no es así en C# y te voy a mostrar el código tanto para C# como para Visual Basic, pues… el código lo escribiré para que sea re-utilizable en C#. Además de que de esta forma, creando y accediendo a los formularios por medio de una variable que nosotros instanciemos, nos evitamos el problema de tener (sin darnos casi cuenta) el mismo formulario abierto dos (o más) veces. Esto último debería resaltarlo, ya que creo que muchos usuarios de Visual Basic le puede ocurrir eso de tener el mismo formulario abierto más de una vez, una de forma automática al llamarlo directamente,. por ejemplo Form2.Show y la otra si previamente hemos creado una variable para acceder a dicho Form2. Ahora verás el ejemplo.

Si necesitamos acceder a la instancia en ejecución del formulario principal (en mi caso Form1) lo que yo hago es definir una variable compartida (Shared en VB y static en C#) llamada Current que es del mismo tipo que el formulario y que instanciamos, por ejemplo en el constructor.

Veamos el código de ejemplo que hay que añadir en el formulario principal (Form1) para definir esa instancia predeterminada y de paso crear el evento y demás métodos que serán necesarios para comunicar al resto de formularios que la fuente del formulario principal ha cambiado.

Empezaré con el código de Visual Basic y después con el de C#, que es algo diferente, al menos en la definición del evento. Pero igualmente te explicaré qué hace cada línea de código 😉

Nota:
Doy por hecho que tienes el código que puse en el artículo anterior, ya que aquí solo te diré (y mostraré) dónde tienes que añadir el código nuevo. Al menos en el Form1, ya que voy a crear otro formulario nuevo (Form2) y ese si te mostraré lo que debes hacer.

El código de Visual Basic a añadir al principio del formulario (en realidad da igual donde lo pongas, pero…)

Public Class Form1

    ''' <summary>
    ''' Instancia del formulario principal
    ''' </summary>
    Public Shared Current As Form1

    ''' <summary>
    ''' Evento para detectar el cambio de fuente
    ''' y avisar a los oyentes.
    ''' </summary>
    Public Event FuenteCambiada(fnt As Font)

    ''' <summary>
    ''' Método privado para lanzar el evento
    ''' </summary>
    Protected Sub OnFuenteCambiada(fnt As Font)
        RaiseEvent FuenteCambiada(fnt)
    End Sub

    Private Sub Form1_FontChanged(sender As Object, e As EventArgs) Handles _
                                                 Me.FontChanged
        OnFuenteCambiada(Me.Font)
    End Sub

Este es el mismo código pero para C#, ya sabes, casi lo mismo pero con puntos y comas 😉

public partial class Form1 : Form
{
    /// <summary>
    /// Instancia del formulario principal
    /// </summary>
    public static Form1 Current;

    /// <summary>
    /// Evento para detectar el cambio de fuente
    /// y avisar a los oyentes.
    /// </summary>
    public event FuenteCambiadaEventHandler FuenteCambiada;

    public delegate void FuenteCambiadaEventHandler(Font fnt);

    /// <summary>
    /// Método privado para lanzar el evento
    /// </summary>
    protected void OnFuenteCambiada(Font fnt)
    {
        FuenteCambiada?.Invoke(fnt);
        //if (FuenteCambiada != null)
        //    FuenteCambiada(fnt);
    }

    private void Form1_FontChanged(object sender, EventArgs e)
    {
        OnFuenteCambiada(this.Font);
    }

Como te dije, Current hará referencia al formulario Form1 que hayamos instanciado al iniciar la aplicación, el hacerlo compartido es para poder acceder usándolo de esta forma: Form1.Current. La asignación la tenemos que hacer en el constructor de la clase (Form1).

'
' El constructor del formulario
'
Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Form1.Current = Me
//
// El constructor del formulario
//
public Form1()
{

    // This call is required by the designer.
    InitializeComponent();

    // Add any initialization after the InitializeComponent() call.
    Form1.Current = this;
    this.FontChanged += Form1_FontChanged;

En C# definimos el evento FontChanged del formulario, cosa que en Visual Basic no es necesario ya que añadiendo al final de la definición del método Handles Me.FontChanged es suficiente.

Sigamos con las explicaciones del código de los listados anteriores.
Definimos un evento llamado FuenteCambiada que define un argumento de tipo Font, en el método OnFuenteCambiada invocamos a dicho evento. En el código de C# te muestro las dos formas de hacerlo, la abreviada y la «clásica».

Ese evento lo lanzaremos cuando la fuente del formulario principal cambie y precisamente el evento FontChanged del formulario es el que nos avisa de que la fuente ha cambiado.

Y esto es todo lo que debes cambiar en el formulario principal.

Ahora vamos a crear un nuevo formulario llamado Form2.

En tiempo de diseño tendrá el siguiente aspecto (figura 1)

Figura 1. El formulario Form2 en tiempo de diseño
Figura 1. El formulario Form2 en tiempo de diseño

Ajusta los valores de Anchor tal como te indico a continuación:
La caja de texto es: Top, Left, Right, el botón: Top, Right y el RichTextBox es: Top, Bottom, Left, Right.

Salvo el RichTextBox, todos los controles tienen la fuente predeterminada, la caja de texto enriquecido lo he puesto con esta fuente: Segoe Script; 36pt; style=Bold.

Los nombres de los controles son: txtSaludo, RichTextBox1 y btnMostrar.

Y este es el código que tendrás que poner en ese formulario o en cualquier otro en el que quieras que se cambien las fuentes al cambiarlas en el formulario principal.

Te muestro primero el código de Visual Basic y después el de C#.

Public Class Form2

    '--------------------------------------------------------------------------
    ' Código a añadir a cada formulario
    ' en los que queramos que sincronicen la fuente
    '
    ' Solo cambiar Form1 por el nombre del formulario
    ' que define el evento FuenteCambiada
    '
    Private Sub FuenteCambiada(fnt As Font)
        Me.Font = fnt
    End Sub

    Private Sub FuenteCambiada_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Font = Form1.Current.Font

        AddHandler Form1.Current.FuenteCambiada, AddressOf FuenteCambiada
    End Sub

    Private Sub FuenteCambiada_FormClosing(sender As Object, e As FormClosingEventArgs) Handles _
                                                            MyBase.FormClosing
        RemoveHandler Form1.Current.FuenteCambiada, AddressOf FuenteCambiada
    End Sub
    '
    ' Fin del código para sincronizar la fuente
    '--------------------------------------------------------------------------

    Private Sub btnMostrar_Click(sender As Object, e As EventArgs) Handles btnMostrar.Click
        RichTextBox1.Text = txtSaludo.Text
    End Sub

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();

        //Form1.Current.FuenteCambiada += FuenteCambiada;

        this.Load += FuenteCambiada_Load;
        this.FormClosing += FuenteCambiada_FormClosing;
    }

    // --------------------------------------------------------------------
    // Código a añadir a cada formulario
    // en los que queramos que sincronicen la fuente
    // 
    // Solo cambiar Form1 por el nombre del formulario
    // que define el evento FuenteCambiada
    // 
    private void FuenteCambiada(Font fnt)
    {
        this.Font = fnt;
    }

    private void FuenteCambiada_Load(object sender, EventArgs e)
    {
        this.Font = Form1.Current.Font;

        Form1.Current.FuenteCambiada += FuenteCambiada;
    }

    private void FuenteCambiada_FormClosing(object sender, FormClosingEventArgs e)
    {
        Form1.Current.FuenteCambiada -= FuenteCambiada;
    }
    //
    // Fin del código para sincronizar la fuente
    // --------------------------------------------------------------------

    private void btnMostrar_Click(object sender, EventArgs e)
    {
        RichTextBox1.Text = txtSaludo.Text;
    }

¡Y esto es todo lo que hay que hacer!

Si ejecutas el programa (recuerda que puedes usar el código que te puse en el artículo anterior y solo añadir el nuevo formulario con el código que te acabo de mostrar).

En la figura 2 puedes ver cómo el segundo formulario (Form2) muestra el tamaño que hayamos indicado en el formulario principal (Form1).

Esto lo consigues cambiando el tamaño en el formulario principal.

Figura 2. La aplicación en funcionamiento mostrando los dos formularios.
Figura 2. La aplicación en funcionamiento mostrando los dos formularios.

Como ves el segundo formulario muestra las fuentes y tamaño de los controles según el porcentaje indicado en el formulario principal. El ojo ese que ves parcialmente es de la foto que tengo de fondo de escritorio 😉

Fíjate también que el RichTextBox solo se ha adaptado al nuevo tamaño del formulario, pero la fuente es del mismo tamaño que estaba definida en tiempo de diseño. Recuerda lo que te dije antes: sólo se cambian las fuente que tiene predeterminadas el diseñador de formularios de Visual Studio.

Solo me falta mostrarte cómo llamar al segundo formulario. Eso lo haremos desde el botón Mostrar Form2 que hay bajo Restablecer fuente. El código es el siguiente:

Private Sub btnForm2_Click(sender As Object, e As EventArgs) Handles btnForm2.Click
    Dim f2 As New Form2
    f2.Font = Me.Font
    f2.Show()

End Sub
private void btnForm2_Click(object sender, EventArgs e)
{
    var f2 = new Form2();
    f2.Font = this.Font;
    f2.Show();
}

Y ahora sí, esto es todo… después (o más tarde) te pongo el enlace con la solución para Visual Studio 2017 con la aplicación completa, tanto para Visual Basic como para C#.

Espero que te sea de utilidad, esa es siempre la intención 😉

Nos vemos.
Guillermo

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#

El zip: Cambiar_tamano_controles_v2.zip (260 KB)

MD5 Checksum: D9C7439F1580CE64228383E7B66BDADA



 


La fecha/hora en el servidor es: 23/11/2024 9:02:59

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024