13

在我的 WPF 应用程序中,我必须在计时器滴答事件中显示进度条进度,如下所示,

System.Windows.Forms.Timer timer;
public MainWindow()
{
    timer = new System.Windows.Forms.Timer();
    timer.Interval = 1000;
    this.timer.Tick += new System.EventHandler(this.timer_Tick);
}

加载事件如下

private void Window_Loaded(object sender, RoutedEventArgs e)
{
      progressBar1.Minimum = 0;
      progressBar1.Value = DateTime.Now.Second;
      progressBar1.Maximum = 700;
      timer.Start();         
 }

最后在tick事件中,

private void timer_Tick(object sender, EventArgs e)
{
    Duration duration = new Duration(TimeSpan.FromSeconds(20));

    //progress bar animation
    System.Windows.Media.Animation.DoubleAnimation doubleanimation = new    System.Windows.Media.Animation.DoubleAnimation(200.0, duration);
    progressBar1.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);
}

当程序的进度条显示两到三个条的进度时,它会停止递增。后来对进度完全没有影响。

为什么?

4

4 回答 4

10

由于您ProgressBar与任何特定行为无关,因此它看起来像是不确定酒吧的工作。

This other SO question提供了一些关于它的见解。简而言之,它是 XAML 单行代码:

<!-- MinVal, MaxVal, Height needed for this to work -->
<ProgressBar x:Name="progressBar1" Margin="5" IsIndeterminate="True" 
    MinimumValue="0" MaximumValue="700" value="0" Height="20"/> 

然后在代码中,你会这样:

progressBar1.IsIndeterminate = true; // start animation
progressBar1.IsIndeterminate = false; // stop animation
于 2013-03-15T10:22:46.730 回答
9

在我的WPF应用程序中,我有...System.Windows.Forms.Timer timer;

那是错误的计时器类型。请改用DispatcherTimer

当我执行我的程序时,进度条显示两三个条的进度,然后它停止

这让我感到惊讶,我根本没想到它会起作用。这意味着您可能还会遇到其他问题,例如阻塞主(调度程序)线程。

您只需在 Loaded 事件中设置一次值:

     progressBar1.Value = DateTime.Now.Second;

progressBar1.ValueTick 事件中的to 没有变化。所以它认为它停止移动。

于 2013-03-15T10:07:03.037 回答
4

使用 DispatcherTimer 代替 Timer(Forms 对象),并使用 ProgressBar 的 Value 属性。

试试这个:

MainWindows.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="55" Width="261">
    <Grid>
        <ProgressBar Name="pb" Maximum="60" />
    </Grid>
</Window>

MainWindows.xaml.cs:

using System.Windows;
using System.Windows.Threading;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        private DispatcherTimer timer;
    
        public MainWindow()
        {
            InitializeComponent();

            this.timer = new DispatcherTimer();
            this.timer.Tick += timer_Tick;
            this.timer.Interval = new System.TimeSpan(0, 0, 1);
            this.timer.Start();
        }

        private void timer_Tick(object sender, System.EventArgs e)
        {
            this.pb.Value = System.DateTime.Now.Second % 100;
        }
    }
}

您可以通过更改 Value 属性来更改进度条的行为(不要忘记在 xaml 中定义 Maximum 属性)。

于 2013-03-15T12:49:11.787 回答
3

我发现这个(WPF Multithreading: Using the BackgroundWorker and Reporting the Progress to the UI.link)包含了一个很好的解决方案来满足我的需求,尽管有一个对话框。

我发现非常有用的一件事是工作线程无法访问 MainWindow 的控件(以它自己的方法)。但是,当在主窗口事件处理程序中使用委托时,这是可能的。

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    pd.Close();
    // Get a result from the asynchronous worker
    T t = (t)args.Result
    this.ExampleControl.Text = t.BlaBla;
};
于 2013-09-23T20:44:14.560 回答