1
votes

I created a little tool for importing and converting data from one database to another. Since this takes a lot of time, I wanted to display some kind of progress for the user with a indeterminate progressbar. As long as the import is running, the progressbar should be running too. I used this site as reference : The ProgressBar control but I got trouble understanding the role of the DoWork-Method since the option for a indeterminate progressbar is set once.

I came up with a solution that works halfway, I can't stop the animation after the import's done. Could someone help me out?

XAML:

 <ProgressBar Minimum="{Binding Path=Minimum}" Maximum="100" IsIndeterminate="{Binding Path=IsIndeterminate}" Height="20" Grid.Column="2" Grid.Row="5" Grid.ColumnSpan="2"/>

ViewModel:

public void StartImportThread()
    {
        ButtonsEnabled = false;
        var th = new Thread(new ThreadStart(StartImport));
        th.IsBackground = true;
        th.Start();
    }
public void StartImport()
    {
        _threadDispatcher = Dispatcher.CurrentDispatcher;
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_Complete;

        worker.RunWorkerAsync();

        // Doing Import Stuff
        worker.CancelAsync(); // Import finished
        ButtonsEnabled=true;
    }
    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
       // while(true)
     //  {
          Minimum = 0;
          IsIndeterminate = true;
    //   }


    }


    private void worker_Complete(object sender, RunWorkerCompletedEventArgs e)
    {
       // if (e.Cancelled)
       // {
            IsIndeterminate = false;
            Minimum = 100;  
       // }

    }
1
Do you mean indeterminate rather than indeterminated? - Jim Mischel
@JimMischel Looks like he does in fact me indeterminate. It would refer to a progress indicator in which you don't actually know how much longer the operation will take, and are merely indicating that progress is indeed being made. - Servy
That's what I meant, it's an indicator for displaying that the import is still running. I also made edits in my question. Thanks for pointing it out. - Scorch
Scorch, your cited code works at my site. Are the IsIndeterminate and Minimum VM properties correctly bound and change-notified? Does the "Doing Import Stuff" ever ends? - Alex Zhmerik
Yes, the import ends as soon as the data is transfered. Did the progressbar stop its animation after "Doing import Stuff"? In my case, the import is finished but the animation is still going. Thanks for the reply. - Scorch

1 Answers

1
votes

Here is what works for me. RelayCommand and ViewModelBase are from MvvmLight library, the DoWorkCommand is called by a button:

        <Button Name="BtnReload" Command="{Binding DoWorkCommand}" Width="75" Height="25"/>
        <ProgressBar Minimum="{Binding Path=Minimum}" Maximum="100" IsIndeterminate="{Binding Path=IsIndeterminate}" Height="20"/>



   public class MainViewModel : ViewModelBase {

    private RelayCommand _doWorkCommand;
    private bool _isIndeterminate;
    private int _minimum;
    private Dispatcher _threadDispatcher;


    public int Minimum {
        get { return _minimum; }
        set {
            _minimum = value;
            RaisePropertyChanged(nameof(Minimum));
        }
    }

    public bool IsIndeterminate {
        get { return _isIndeterminate; }
        set {
            _isIndeterminate = value;
            RaisePropertyChanged(nameof(IsIndeterminate));
        }
    }

    public MainViewModel(IDataService dataService) {

    }

    public void StartImportThread() {
        //  ButtonsEnabled = false;
        var th = new Thread(new ThreadStart(StartImport));
        th.IsBackground = true;
        th.Start();
    }

    public void StartImport() {
        _threadDispatcher = Dispatcher.CurrentDispatcher;
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_Complete;

        worker.RunWorkerAsync();

        // Doing Import Stuff
        worker.CancelAsync(); // Import finished
        //   ButtonsEnabled = true;

    }

    void worker_DoWork(object sender, DoWorkEventArgs e) {
        Minimum = 0;
        IsIndeterminate = true;
        //for (int i = 0; i < 30; i++) {
        //    Thread.Sleep(100);
        //}     
    }

    void worker_Complete(object sender, RunWorkerCompletedEventArgs e) {
        IsIndeterminate = false;
        Minimum = 100;
    }

    public RelayCommand DoWorkCommand => _doWorkCommand ??
        (_doWorkCommand = new RelayCommand(() => StartImportThread()));

}