none
WPF ProgressBar - Mostra lo strato di caricamento RRS feed

  • Domanda

  • Ciao ho il seguente problema ho creato una progressBar in WPF:

     <ProgressBar x:Name="r_loag" Margin="0,0,0,0"  Minimum="0" Maximum="100" Value="0" Grid.Column="0" Visibility="Hidden"  Background="#002362DF" Foreground="#7F2266D9" IsIndeterminate="False"></ProgressBar>

    Ho creato una funzione per leggere i dati all'interno di un DataBase, in questa funzione ho inserito il comando

    r_loag.Value++;

    (prima ho modificato Maximum con il numero di valori presenti nel DB)

    Il problema è che la progressBar non mostra l'avanzamento ma si attiva solo alla fine del ciclo di caricamento dei dati mostrando subito la barra piena al 100%.

    Come posso fare per fare l'aggiornamento della progressBar ogni volta che il valore cambia all'interno del ciclo?

    Grazie

    lunedì 1 luglio 2019 14:13

Risposte

  • Ciao,

    la progress bar si attiva solo alla fine dell'esecuzione del "caricamento" che tu effettui perché il metodo che tu stai eseguendo si trova sul Thread principale dell'applicazione, pertanto blocca la User Interface per la sua durata, se vuoi che venga aggiornata la status bar durante il ciclo hai 2 possibilità:

    1) Spostare l'esecuzione del caricamento su un thread diverso (utilizzando ad esempio un metodo async ed un Task) per eseguire l'operazione.

    2) Fare in modo che quando aggiorni la status bar venga "interrotto" il ciclo che stai eseguendo ridando il controllo alla UI in modo che possa eseguire l'aggiornamento, simulando quello che in WIndows Forms si chiama DoEvents.

    Questo lo puoi fare utilizzando uno snippet di codice che uso spesso anche io quando ad esempio carico dati su una window e devo comunque fare attendere il mio utente quindi l'uso di un async - await non da molto vantaggio.

    Ti scrivo lo snippet di codice che uso io:

    //QUeste clausole using vanno messe 
    //nella classe
    using System.Security.Permissions;
    using System.Windows.Threading;
    
    //I due metodi qui sotto emulano il DoEvents di WinForms
    
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
            public void DoEvents()
            {
                DispatcherFrame frame = new DispatcherFrame();
                Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                    new DispatcherOperationCallback(ExitFrame), frame);
                Dispatcher.PushFrame(frame);
            }
    
            public object ExitFrame(object f)
            {
                ((DispatcherFrame)f).Continue = false;
    
                return null;
            }
    
    //Dove aggiorni la statusbar, aggiungi la chiamata a DoEvents()
    
    //Ad esempio
    
    UpdateMyStatusBar(35);
    DoEvents();
    
    
    
    

    Solitamente io implemento i 2 metodi in un Helper che utilizzo poi in tutta l'applicazione.

    saluti


    Sabrina C. - http://www.dotnetwork.it

    • Contrassegnato come risposta StarSquare martedì 2 luglio 2019 17:47
    lunedì 1 luglio 2019 14:38

Tutte le risposte

  • Ciao,

    la progress bar si attiva solo alla fine dell'esecuzione del "caricamento" che tu effettui perché il metodo che tu stai eseguendo si trova sul Thread principale dell'applicazione, pertanto blocca la User Interface per la sua durata, se vuoi che venga aggiornata la status bar durante il ciclo hai 2 possibilità:

    1) Spostare l'esecuzione del caricamento su un thread diverso (utilizzando ad esempio un metodo async ed un Task) per eseguire l'operazione.

    2) Fare in modo che quando aggiorni la status bar venga "interrotto" il ciclo che stai eseguendo ridando il controllo alla UI in modo che possa eseguire l'aggiornamento, simulando quello che in WIndows Forms si chiama DoEvents.

    Questo lo puoi fare utilizzando uno snippet di codice che uso spesso anche io quando ad esempio carico dati su una window e devo comunque fare attendere il mio utente quindi l'uso di un async - await non da molto vantaggio.

    Ti scrivo lo snippet di codice che uso io:

    //QUeste clausole using vanno messe 
    //nella classe
    using System.Security.Permissions;
    using System.Windows.Threading;
    
    //I due metodi qui sotto emulano il DoEvents di WinForms
    
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
            public void DoEvents()
            {
                DispatcherFrame frame = new DispatcherFrame();
                Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                    new DispatcherOperationCallback(ExitFrame), frame);
                Dispatcher.PushFrame(frame);
            }
    
            public object ExitFrame(object f)
            {
                ((DispatcherFrame)f).Continue = false;
    
                return null;
            }
    
    //Dove aggiorni la statusbar, aggiungi la chiamata a DoEvents()
    
    //Ad esempio
    
    UpdateMyStatusBar(35);
    DoEvents();
    
    
    
    

    Solitamente io implemento i 2 metodi in un Helper che utilizzo poi in tutta l'applicazione.

    saluti


    Sabrina C. - http://www.dotnetwork.it

    • Contrassegnato come risposta StarSquare martedì 2 luglio 2019 17:47
    lunedì 1 luglio 2019 14:38
  • Grazie ho fatto copia incolla del tuo snippet e funziona alla perfezione
    martedì 2 luglio 2019 17:47