Usar un PrgressBar manejado asíncronamente con un delegado para componer una ventana del tipo [Espera]
En este documento se muestra una ventana espera que se muestra tal y como parece en la siguiente imagen
<Window x:Class="WindowEsperaAsync" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="Window Espera Dos" WindowStyle="None" Background="#00FFFFFF" AllowsTransparency="True" MouseDown="Window_MouseDown" MouseRightButtonDown="Window_MouseRightButtonDown" Height="200" Width="320"> <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="10" Background="#FFE9DBF9" > <Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="30" /> <RowDefinition Height="30" /> <RowDefinition Height="30" /> <RowDefinition Height="30" /> </Grid.RowDefinitions> <Label x:Name="labelTitulo" Grid.Row="0" Content="Espera.... Estoy trabajando (mas o menos) " HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" VerticalAlignment="Top" Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" /> <ProgressBar x:Name="ProgressBarSuperior" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Height="15" Background="#FFE8F1F0" /> <ProgressBar x:Name="ProgressBarInferior" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" Height="15" Background="#FFCEF5B8" /> <Label x:Name="labelHoraInicio" Grid.Row="3" Content="Proceso iniciado " HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" VerticalAlignment="Top" VerticalContentAlignment="Center"/> <Label x:Name="labelTiempoInvertido" Grid.Row="4" Content="Tiempo Invertido " HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" VerticalAlignment="Top" VerticalContentAlignment="Center"/> </Grid> </Border> </Window>
' /** ' --------------------------------------------- ' [- (A) Contenido -] ' --------------------------------------------- ' [- Versión -] = 18.01.16.0916 ' [- Class Name -] = WindowEsperaAsync ' [- Descripción -] = ' Ventana que emite el mensaje de espera. ' También mueve dos barras de progreso, para dar la impresión de que ' hace algo ' --------------- ' [- Bibliografía -] = ' WPF ProgressBar. ' https://www.codeproject.com/Articles/38555/WPF-ProgressBar ' --------------- ' [- Código de ejemplo -] = ' ' --------------------------------------------- ' [- (B) Información básica -] ' --------------------------------------------- ' [- Lenguaje -] = es-ES (Español - España) ' [- Type -] = Visual Basic Source file ' [- Size -] = 6,12 KB ' --------------------------------------------- ' [- (D) Revisiones -] ' --------------------------------------------- ' [- Historial de revisiones -] = - 2018/01/16 - Creación. ' --------------------------------------------- ' [- /Eof -] ' */ Option Explicit On Option Strict On Option Infer Off Option Compare Binary ''' <summary> ''' Ventana [Espera] que mueve un progress bar para simular que hace algo ''' </summary> ''' <remarks> ''' <code> ''' WPF ProgressBar ''' https://www.codeproject.com/Articles/38555/WPF-ProgressBar ''' </code> ''' </remarks> Public Class WindowEsperaAsync #Region "Código [VentanaEspera] para copiar en las clases clientes" ' '''' <summary> '''' variable que contiene el objeto ventana '''' </summary> 'Private WithEvents VentanaEspera As WindowEsperaAsync ' '''' <summary> '''' Proceso para abrir la ventana '''' solo se abre una ventana '''' </summary> 'Public Sub AbrirVentana() ' ' si la ventana no esta activa ' If VentanaEspera Is Nothing Then ' ' Instanciarla ' VentanaEspera = New WindowEsperaAsync With { ' .Owner = Me, ' .WindowStartupLocation = WindowStartupLocation.CenterOwner ' } ' 'Mostrarla ' VentanaEspera.Show() ' ' Iniciar las ProgressBar ' VentanaEspera.ZArrancaProcesoProgressBar() ' End If 'End Sub ' '''' <summary> '''' Proceso para cerrar la ventana '''' </summary> 'Public Sub CerrarVentana() ' ' si la ventana no esta cerrada ' If Not (VentanaEspera Is Nothing) Then ' ' llamar al proceso de cancelación (terminar la ejecución del incremento de las barras de tareas) ' VentanaEspera.ZCancelarProceso() ' ' cerrar la ventana ' VentanaEspera.Close() ' '------- ' ' NOTA ' ' En el evento [VentanaEspera.Closed] Que esta un poco mas abajo :-) ' ' se da el valor NULL a la ventana --> VentanaEspera = Nothing ' End If 'End Sub ' '''' <summary> '''' Evento que se produce cuando se esta cerrando la venta espera '''' ' lo que hago es declararla NULL '''' </summary> 'Private Sub VentanaEspera_Closed(sender As Object, e As EventArgs) Handles VentanaEspera.Closed ' VentanaEspera = Nothing 'End Sub ' #End Region #Region "Eventos de la ventana" ' se usa para mover la ventana pulsando el botón izquierdo del ratón Private Sub Window_MouseDown(sender As Object, e As MouseButtonEventArgs) Me.DragMove() End Sub ' se usa para CERRAR la ventana pulsando el botón derecho del ratón Private Sub Window_MouseRightButtonDown(sender As Object, e As MouseButtonEventArgs) Me.Close() End Sub ' cuando se esta cerrando la ventana hay que decir que se cancele el proceso de aumentar las barras de tarea Private Sub WindowEsperaAsync_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing campoCancelarProceso = True End Sub #End Region #Region "Variables y propiedades y funciones" ' Campo que contiene el valor de cancelación [True, o False] Private campoCancelarProceso As Boolean = False ''' <summary> ''' Función que inicia la cancelación del proceso ''' </summary> Public Sub ZCancelarProceso() campoCancelarProceso = True End Sub ''' <summary> ''' Delegado que coincide con la firma del método ProgressBar value (SetValue) ''' </summary> Private Delegate Sub UpdateProgressBarDelegate( ByVal dp As System.Windows.DependencyProperty, ByVal value As Object) ''' <summary> ''' Proceso que arranca las barras de progress bar ''' y usa el delegado recién creado ''' </summary> Public Sub ZArrancaProcesoProgressBar() campoCancelarProceso = False ' Para el tiempo Dim objStopWatch As Stopwatch objStopWatch = New Stopwatch Try objStopWatch.Start() labelHoraInicio.Content = String.Format("Proceso iniciado el día {0} a las {1}", Date.Now.ToShortDateString, Date.Now.ToLongTimeString) 'Valores in1ciales del ProgressBarSuperior ProgressBarSuperior.Minimum = 0 ProgressBarSuperior.Maximum = 10 ProgressBarSuperior.Value = 0 'Valores in1ciales del ProgressBarInferior ProgressBarInferior.Minimum = 0 ProgressBarInferior.Maximum = Short.MaxValue ProgressBarInferior.Value = 0 ' Instanciar el delegado para el ProgressBarSuperior Dim updateProgressBarSuperiorDelegate As New _ UpdateProgressBarDelegate(AddressOf ProgressBarSuperior.SetValue) ' Instanciar el delegado para el ProgressBarInferior Dim updateProgressBarInferiorDelegate As New _ UpdateProgressBarDelegate(AddressOf ProgressBarInferior.SetValue) ' Bucle exterior ' Hasta que ProgressBar.Value alcance el máximo For valueProgressBarSuperior As Double = 0 To ProgressBarSuperior.Maximum ' actualizar el valor del ProgressBarSuperior Dispatcher.Invoke(updateProgressBarSuperiorDelegate, System.Windows.Threading.DispatcherPriority.Background, New Object() {ProgressBar.ValueProperty, valueProgressBarSuperior}) 'Valores in1ciales del ProgressBarInferior ' que se ponen a cero en cada vuelta del bucle exterior ProgressBarInferior.Minimum = 0 ProgressBarInferior.Maximum = Short.MaxValue ProgressBarInferior.Value = 0 ' Bucle interior For valueProgressBarInferior As Double = 0 To ProgressBarInferior.Maximum ' el tiempo invertido ' Obtener el tiempo transcurrido (elapsed) como un valor TimeSpan Dim ts As TimeSpan = objStopWatch.Elapsed ' Formatear y mostrar el valor del tiempo. Me.labelTiempoInvertido.Content = String.Format("{0,-20} : {1}", "Tiempo invertido", FormatoTiempo(ts)) 'Proceso de cancelación (si procede) If Me.campoCancelarProceso = True Then Exit Try End If '-------------------------------------------------------------- 'Actualiza el valor de ProgressBar: '1) Pasar el delegado "updateProgressBarInferiorDelegate" ' que apunta al método ProgressBarInferior.SetValue '2) Establecer la prioridad de Dispatcher en "segundo plano" '3) Pase una matriz Object) que contiene la propiedad que ' hay que actualizar (ProgressBar.ValueProperty) y su nuevo valor (valorDos) Dispatcher.Invoke(updateProgressBarInferiorDelegate, System.Windows.Threading.DispatcherPriority.Background, New Object() {ProgressBar.ValueProperty, valueProgressBarInferior}) Next '/ProgressBarInferior Next '/ valueProgressBarSuperior Catch ex As Exception Throw Finally ProgressBarSuperior.Value = ProgressBarSuperior.Maximum ProgressBarInferior.Value = ProgressBarInferior.Maximum objStopWatch.Stop() objStopWatch = Nothing End Try End Sub ''' <summary> ''' Formatea en una cadena el tiempo que recibe por parámetro ''' </summary> ''' <param name=paramElapsedTime">el valor de tiempo</param>" ''' <returns>Una cadena formateada. por ejemplo [04 horas, 02 minutos , 50 segundos] </returns> ''' <remarks> ''' Función copiada el día 2018/01/16 de la clase [PorcentajeRealizado] ''' </remarks> Private Shared Function FormatoTiempo(ByVal paramElapsedTime As TimeSpan) As String ' [ 02 días, 04 horas, 02 minutos , 50 segundos ] ' [ 04 horas, 02 minutos , 50 segundos] ' [ 02 minutos , 50 segundos] ' [ 50 segundos] ' [ Menos de 10 segundos] If paramElapsedTime.Days > 0 Then Return String.Format("{0:00} días y {1:00}:{2:00}:{3:00} Horas", paramElapsedTime.Days, paramElapsedTime.Hours, paramElapsedTime.Minutes, paramElapsedTime.Seconds) End If If paramElapsedTime.Hours > 0 Then Return String.Format("{0:00}:{1:00}:{2:00} Horas", paramElapsedTime.Hours, paramElapsedTime.Minutes, paramElapsedTime.Seconds) End If If paramElapsedTime.Minutes > 0 Then Return String.Format("{0:00}:{1:00} Minutos ", paramElapsedTime.Minutes, paramElapsedTime.Seconds) End If If paramElapsedTime.Seconds > 10 Then Return String.Format("{0:00}.{1:00} segundos", paramElapsedTime.Seconds, paramElapsedTime.Milliseconds / 10) End If If paramElapsedTime.Seconds > 0 Then Return String.Format("Menos de {0:00} segundos", paramElapsedTime.Seconds) End If Return " /Eof. Proceso terminado (¿o no?)" End Function #End Region End Class
Private Sub button0Abrir_Click(sender As Object, e As RoutedEventArgs) Call AbrirVentana() End Sub Private Sub button1Cerrar_Click(sender As Object, e As RoutedEventArgs) Call CerrarVentana() End Sub #Region "Código [VentanaEspera] para copiar en las clases clientes" ''' <summary> ''' variable que contiene el objeto ventana ''' </summary> Private WithEvents VentanaEspera As WindowEsperaAsync ''' <summary> ''' Proceso para abrir la ventana ''' solo se abre una ventana ''' </summary> Public Sub AbrirVentana() ' si la ventana no esta activa If VentanaEspera Is Nothing Then ' Instanciarla VentanaEspera = New WindowEsperaAsync With { .Owner = Me, .WindowStartupLocation = WindowStartupLocation.CenterOwner } 'Mostrarla VentanaEspera.Show() ' Iniciar las ProgressBar VentanaEspera.ZArrancaProcesoProgressBar() End If End Sub ''' <summary> ''' Proceso para cerrar la ventana ''' </summary> Public Sub CerrarVentana() ' si la ventana no esta cerrada If Not (VentanaEspera Is Nothing) Then ' llamar al proceso de cancelación (terminar la ejecución del incremento de las barras de tareas) VentanaEspera.ZCancelarProceso() ' cerrar la ventana VentanaEspera.Close() '------- ' NOTA ' En el evento [VentanaEspera.Closed] Que esta un poco mas abajo :-) ' se da el valor NULL a la ventana --> VentanaEspera = Nothing End If End Sub ''' <summary> ''' Evento que se produce cuando se esta cerrando la venta espera ''' ' lo que hago es declararla NULL ''' </summary> Private Sub VentanaEspera_Closed(sender As Object, e As EventArgs) Handles VentanaEspera.Closed VentanaEspera = Nothing End Sub #End Region
© 1997 - - La Güeb de Joaquín | |||||
Joaquín Medina Serrano
|
|||||
|
Codificación | |
Fecha de creación | |
Última actualización | |