用.net 4.0更新WPF模型中的进度条

本文关键字:模型 WPF net 更新 | 更新日期: 2023-09-27 18:11:50

我正在编写一个执行耗时任务的应用程序(在。net 4中,而不是 4.5),该任务被保存在一个模型中。例如:

CalculatorModel.cs:

private void Execute(){
   for(int x=0; x<100; x++){
      // do task
      //then report progress
   }
}

我的mainwindow . example .cs是这样的:

public MainWindow()
{
   InitializeComponent();    
}
private void buttonCalculate_Click(object sender, RoutedEventArgs e)
{
   CalculatorModel calculator = new CalculatorModel();
   calculator.Execute();      
}

我宁愿不要在mainwindow . example .cs的线程中完成所有的处理。我读到有IProgress可以执行这个任务,但它似乎只有。net 4.5。

用.net 4.0更新WPF模型中的进度条

创建BackgroundWorker。在它的DoWork事件中做繁重的(阅读费时的)工作,并使用事件ProgressChanged不断更新UI进度。

更多信息请阅读BackgroundWorker组件和MVVM

使用服务类概念的简单示例,假设您只需要一个进度条

xaml

<ProgressBar xmlns:l="clr-namespace:CSharpWPF"
             Value="{Binding CurrentProgress,Source={x:Static l:ProgressService.Instance}}" />
cs

namespace CSharpWPF
{
    class ViewModel : DependencyObject
    {
        public ViewModel()
        {
            DispatcherTimer dt = new DispatcherTimer();
            dt.Interval = TimeSpan.FromSeconds(1);
            dt.Tick += (s, e) => ProgressService.Instance.CurrentProgress += 10;
            dt.Start();
        }
    }
    class ProgressService : DependencyObject
    {
        static ProgressService()
        {
            Instance = new ProgressService();
        }
        public static ProgressService Instance { get; private set; }
        public double CurrentProgress
        {
            get { return (double)GetValue(CurrentProgressProperty); }
            set { SetValue(CurrentProgressProperty, value); }
        }
        // Using a DependencyProperty as the backing store for CurrentProgress.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentProgressProperty =
            DependencyProperty.Register("CurrentProgress", typeof(double), typeof(ProgressService), new PropertyMetadata(0.0));
    }
}

因此,通过操作静态属性ProgressService.Instance.CurrentProgress,您可以从代码的任何部分报告进度。

所有的答案都未能解决这个问题,所以我将自己回答,以备将来参考:

在mainwindow . example .cs::

public MainWindow()
{
   InitializeComponent();
   progressBar.Maximum = 1000;
   bw.WorkerReportsProgress = true;
   bw.WorkerSupportsCancellation = true;
   Calculator calc = new Calculator();
   bw.DoWork += new DoWorkEventHandler(calc.bw_DoWork);
   bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
   bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
}
// the rest of the threading methods here

在CalculatorModel.cs中:

public void bw_DoWork(object sender, DoWorkEventArgs e)
{
      BackgroundWorker worker = sender as BackgroundWorker;
      if ((worker.CancellationPending == true))
      {
         e.Cancel = true;
      }
      else
      {
      for (int x = 0; x < 1000; x++)
      {
         System.Threading.Thread.Sleep(10);
         worker.ReportProgress(x);
      }
   }
}