WPF ProgressBar

Descripción general

Este artículo muestra cómo utilizar un WPF en un "bucle de código apretado".ProgressBar

WPF - ProgressBar

Durante años, barras de progreso han sido muy útiles y muy fáciles de usar en aplicaciones de formularios Windows Forms normales.

Las barras de progreso WPF son conceptualmente las mismas barras de progreso de Windows; sin embargo, hay una diferencia muy notable: Las barras de progreso de WPF no se actualizan correctamente mientras se procesa la aplicación. Esto crea un efecto muy indeseable, especialmente puesto que el propósito de la barra de progreso es precisamente eso, un "Informe de los progresos".

Hay muchas situaciones donde se requieren "bucles rígidos" en código, como cuando se lee datos de un archivo. Es casi un estándar de codificación, abrir el archivo, luego recorrer el archivo entero, líneas, caracteres o bytes en cada paso de la lectura. Normalmente se utiliza (siempre) Una barra de progreso para informar el progreso de esta operación. Pero… la Barra de progreso no se actualiza correctamente.

Este artículo aborda específicamente este tema y muestra cómo utilizar en WPF un control ProgressBar en un "bucle de código".

'Crear un delegado que coincida con
'La firma del método SetValue de ProgressBar
Private Delegate Sub UpdateProgressBarDelegate(
    ByVal dp As System.Windows.DependencyProperty,
    ByVal value As Object)



Private Sub ProcesoCualquiera()
    '-------------------------------------------------------
    ' Bibliografía
    ' https://www.codeproject.com/Articles/38555/WPF-ProgressBar
    '-------------------------------------------------------

    ' Crear una nueva instancia de nuestro delegado de 
    ' [barra de progreso] que apunte al 
    ' método ProgressBar SetValue.
    Dim updatePbDelegate As New UpdateProgressBarDelegate(AddressOf ProgressBarPorcentaje.SetValue)

    'Bucle que simula un bloque de operaciones

    'NOTA
    ' Se declara como double, porque la propiedad [value], del control [ProgressBar]
    ' esta definida como [Double]. Si se le da otro tipo se produce un error
    For ValorNumerico As Double = 1 To 80

    'Actualiza el valor del control ProgressBar:
    '1) Pasa la variable local que instancia el delegado [updatePbDelegate] 
    '   para apuntar al método ProgressBar1.SetValue 
    '   (definido en el delegado [UpdateProgressBarDelegate])
    '2) Establece DispatcherPriority en "Background"
    '3) Pasa un [Array  Object()] que contiene la propiedad para actualizar 
    '   (ProgressBar.ValueProperty) y el nuevo valor (ValorNumerico)
        Dispatcher.Invoke(updatePbDelegate,
            System.Windows.Threading.DispatcherPriority.Background,
    New Object() {ProgressBar.ValueProperty, ValorNumerico})

    ' simular un proceso largo
        System.Threading.Thread.Sleep(200)

    Next
End Sub

↑↑↑

Version personalizada de un control ProgresBar [2021/11/20]

El código Xaml

    <Grid>
        <Button x:Name = "ButtonPruebas" Content = "Prueba"
                HorizontalAlignment = "Left"  VerticalAlignment = "Top"
                Width = "75" Margin = "87,33,0,0"
                Click = "ButtonPruebas_Click"/>

        <Dll_Wpf_UC_Libreria_2020:MyWpfProgressBar
            x:Name = "MyWpfProgressBar"
            HorizontalAlignment = "Left"  VerticalAlignment = "Top"
            Width = "205" Height = "20" Margin = "110,271,0,0"/>

   
    </Grid>

El código de la clase que hereda un ProgressBar


''' <summary>
'''   Control ProgressBar extendido
''' </summary>
Public Class MyWpfProgressBar
    Inherits ProgressBar

    'Crear un delegado que coincida con
    'La firma del método SetValue de ProgressBar
    Private Delegate Sub UpdateProgressBarDelegate(
                     ByVal dp As System.Windows.DependencyProperty,
                     ByVal value As Object)

    ' Crear una nueva instancia de nuestro delegado de
    ' [barra de progreso] que apunte al
    ' método ProgressBar SetValue.
    Dim updatePbDelegate As New UpdateProgressBarDelegate(AddressOf Me.SetValue)

    ' Sobreescribir [Overloads] la propiedad value del ProgreesBar base 
    Public Overloads Property Value As Double
        Get
            Return MyBase.Value
        End Get
        Set(auxValue As Double)
            'Actualiza el valor del control ProgressBar:
            '1) Pasa la variable local que instancia el delegado [updatePbDelegate]
            '   para apuntar al método ProgressBar1.SetValue
            '   (definido en el delegado [UpdateProgressBarDelegate])
            '2) Establece DispatcherPriority en "Background"
            '3) Pasa un [Array  Object()] que contiene la propiedad para actualizar
            '   (ProgressBar.ValueProperty) y el nuevo valor (ValorNumerico)
            Dispatcher.Invoke(updatePbDelegate,
            System.Windows.Threading.DispatcherPriority.Background,
            New Object() {ProgressBar.ValueProperty, auxValue})
        End Set
    End Property
End Class

Usando el código

    Private Sub ButtonPruebas_Click(sender As Object, e As RoutedEventArgs)
        Call ProcesoCualquiera()
    End Sub

    Private Sub ProcesoCualquiera()
         'Bucle que simula un bloque de operaciones
         For ValorNumerico As Double = 1 To 80
                MyWpfProgressBar.Value = ValorNumerico
                ' simular un proceso largo
                System.Threading.Thread.Sleep(50)
         Next
     End Sub

↑↑↑

A.2.Enlaces

[Para saber mas]
[Grupo de documentos]
[Documento Index]
[Documento Start]
[Imprimir el Documento]
© 1997 - - La Güeb de Joaquín
Joaquín Medina Serrano
Ésta página es española

Codificación
Fecha de creación
Última actualización
[HTML5 Desarrollado usando CSS3]