Una chorradita, pero que queda muy molona…

Buenas!

En este artículo vamos a crear un formulario que muestre un mensaje de espera, por si tenemos que hacer una tarea que requiera tiempo, para distraer un poco al usuario. Además vamos a realizar un fundido del formulario, para que aparezca poco a poco.

En este ejemplo vamos a utilizar multithreading, al estilo de lo comentado en este artículo, (no me preguntéis dónde está el código fuente de este artículo, porque pese a que los adjuntos están en el servidor – no sé dónde – no se muestran en los artículos – ayudaaa!).

Antes de entrar en la chicha, unos pocos preparativos:

  1. Vamos a crear un nuevo formulario en nuestro proyecto. Le llamaremos FrmEspera.
  2. A este formulario le quitamos el borde (FormBorderStyle=None).
  3. Además, le quitamos el texto (Text=””). Así conseguiremos que se oculte completamente el borde del mismo, quedando como un panel flotante.
  4. Por último, establecemos la propiedad StartPosition=CenterScreen, para que cuando mostremos el formulario aparezca siempre en el centro de la pantalla.
  5. Para que quede bonito, le ponemos una imagen de fondo al formulario, un control PictureBox para mostrar un icono, y una etiqueta (control Label).

Ahora, vamos al grano: Sería interesante poder modificar el texto a mostrar en el formulario (para usarlo en diferentes situaciones), y la imagen a mostrar. Para esto, en el código del formulario declaramos un par de propiedades:

Public Property ImagenAMostrar() As Image
   Get
      Return pictureBox1.Image
   End Get
   Set(ByVal value As Image)
      pictureBox1.Image = value
   End Set
End Property
 
Public Property MensajeAMostrar() As String
   Get
      Return label1.Text
   End Get
   Set(ByVal value As String)
      label1.Text = value
   End Set
End Property

Como vamos a utilizar varios hilos, vamos a crear un tipo delegado que nos va a permitir invocar desde el hilo en el que vamos a controlar el cambio de la opacidad del formulario el método que realmente cambiará la opacidad del mismo. Esto es necesario para evitar excepciones derivadas del hecho de cambiar una propiedad de un formulario desde un hilo diferente a aquél en el que se creó.

Public Delegate Sub SetOpacityDelegate(ByVal op As Double)
Private dlg As New SetOpacityDelegate(AddressOf Me.SetOpacity)
 
Private Sub SetOpacity(ByVal op As Double)
   Me.BringToFront()
   Me.Opacity = op
   ' Esto es feo, pero necesitamos que se procesen los eventos pendientes...
   Application.DoEvents()
   If op = 0.0F Then
      Me.Close()
   End If
End Sub

Por último, vamos a crear los métodos que usaremos para mostrar y ocultar el formulario. Les vamos a llamar FadeIn y FadeOut:

Public Sub FadeIn()
   Me.Opacity = 0.0F
   Me.Show()
   Dim dlg As New System.Threading.ThreadStart(AddressOf Me.doFadeIn)
   dlg.Invoke()
End Sub
 
Public Sub FadeOut()
   Dim dlg As New System.Threading.ThreadStart(AddressOf Me.doFadeOut)
   dlg.Invoke()
End Sub
 
Private Sub doFadeIn()
   For op As Double = 0.1F To 1.0F Step 0.1F
      If InvokeRequired Then
         Me.Invoke(dlg, op)
      Else
         Me.SetOpacity(op)
      End If
      System.Threading.Thread.Sleep(50)
   Next
   Me.Invoke(dlg, 1.0F)
End Sub
 
Private Sub doFadeOut()
   For op As Double = 1.0F To 0.1F Step -0.1F
      If InvokeRequired Then
         Me.Invoke(dlg, op)
      Else
         Me.SetOpacity(op)
      End If
      System.Threading.Thread.Sleep(50)
   Next
   Me.Invoke(dlg, 0.0F)
End Sub

Como podemos ver, en el método FadeIn y en el método FadeOut, hacemos prácticamente lo mismo: Inicializamos un hilo que llamará al método que se encarga de realizar un bucle variando la opacidad del formulario. Y en este método hacemos un bucle en el que se comprueba si estamos en el hilo de la interfaz de usuario o en otro (llamando a InvokeRequired), si bien no es necesario hacerlo, ya que esa condición siempre será verdadera por cómo llamamos a los métodos doFadeIn y doFadeOut, y se llama al método que cambia la opacidad a través de un delegado si estamos en un hilo diferente, o directamente si estamos en el hilo de la interfaz de usuario.

¿Cómo usaríamos este formulario? Pues de la siguiente manera:

Dim frmMsg As New FrmEspera
frmMsg.MensajeAmostrar = "Por favor, espere. Estoy haciendo algo MUY importante"
frmMsg.ImagenAMostrar = Me.ImageList1.Images("ImagenEspera")
frmMsg.FadeIn()
 
' Hacemos la tarea pesada aquí...
 
frmMsg.FadeOut()

Bueno… Pues eso es todo por hoy.

Saludos!

2 comentarios en “Una chorradita, pero que queda muy molona…”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *