如何在MVVM中制作工作进度条?

时间:2016-05-05 10:54:15

标签: wpf mvvm prism

我有一个像这样的进度条:

<ProgressBar x:Name="import_bar" Minimum="0"  Maximum="100" Orientation="Horizontal"  Value="{Binding CurrentProgress, Mode=OneWay}" /> 

和ViewModel:

public class ViewImportProgressViewModel  : BindableBase
    {   
        MainTest mainTest;

        public double CurrentProgress { get; set; }

        public ViewImportProgressViewModel(MainTest mainTest) //constructor
        {
            this.mainTest = mainTest;
            mainTest.ProgressUpdated += SetProgressBarValue;
        }

         private void SetProgressBarValue(double argument)
        {

            CurrentProgress = argument * 100;
            OnPropertyChanged(() => CurrentProgress);
        }

    }

以及实际设置进度值的测试类:

public class MainTest
    {
        public delegate void ProgressUpdateHandler(double argument);
        public event ProgressUpdateHandler ProgressUpdated;

        public void RunTheLoop()
        {
            double progress=0;

            for (int i = 1; i <= 30; i++)
                {
                    //lenghty task code

                    .......


                    //increment the progress bar
                    progress += 1 / 30;


                    if (i == 30)
                        progress = 1;


                    ProgressUpdated(progress);

                }

        }

    }

代码运行正常,我看到CurrentProgress获取正确的值,但UI中的进度条不会更新。有人可以帮帮我吗?

更新

如果我在代码中使用非MVVM方法,就像这样:

 public delegate void UpdateProgressBarDelegate(System.Windows.DependencyProperty dp, Object value);            
 UpdateProgressBarDelegate updatePbDelegate = new UpdateProgressBarDelegate(progress_bar.SetValue);
 Dispatcher.Invoke(updatePbDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { System.Windows.Controls.ProgressBar.ValueProperty, CurrentProgress });

然后它有效。

1 个答案:

答案 0 :(得分:1)

这是一种相当粗略的方法,但它确实可以使用MVVM方法

<强> MainTest

public class MainTest
{
    public delegate void ProgressUpdateHandler(double argument);
    public event ProgressUpdateHandler ProgressUpdated;

    public void RunTheLoop()
    {
        // This does not work
        //this.PerformStuff();

        // This does
        Task.Factory.StartNew(() => this.PerformStuff());
    }

    private void PerformStuff()
    {
        double progress = 0;

        for (int i = 1; i <= 30; i++)
        {
            Thread.Sleep(1000);

            //increment the progress bar
            progress += 1.0 / 30;


            if (i == 30)
                progress = 1;


            ProgressUpdated(progress);

        }
    }
}

查看

public partial class MainWindow : Window
{
    private MainTest test;

    public MainWindow()
    {
        InitializeComponent();

        this.test = new MainTest();
        this.DataContext = new ViewImportProgressViewModel(this.test);

        this.Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        this.test.RunTheLoop();
    }
}

<强>视图模型

public class ViewImportProgressViewModel : INotifyPropertyChanged
{
    MainTest mainTest;

    public event PropertyChangedEventHandler PropertyChanged;

    public double CurrentProgress { get; set; }

    public ViewImportProgressViewModel(MainTest mainTest) //constructor
    {
        this.mainTest = mainTest;
        mainTest.ProgressUpdated += SetProgressBarValue;
    }

    private void SetProgressBarValue(double argument)
    {

        CurrentProgress = argument * 100;

        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentProgress"));
    }

}