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:
- Vamos a crear un nuevo formulario en nuestro proyecto. Le llamaremos FrmEspera.
- A este formulario le quitamos el borde (FormBorderStyle=None).
- Además, le quitamos el texto (Text=»»). Así conseguiremos que se oculte completamente el borde del mismo, quedando como un panel flotante.
- Por último, establecemos la propiedad StartPosition=CenterScreen, para que cuando mostremos el formulario aparezca siempre en el centro de la pantalla.
- 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!
Te ha faltado el avioncito volando
Te ha faltado el 380 despegando y aterrizando. !Pa la proxima!