1

我正在编写一个显示某个耗时任务状态的 WPF 应用程序。

我有一个 TextBlock 绑定到任务的开始时间,我还有另一个 TextBlock 用于显示在所述任务上花费的时间量。

使用与转换器的简单绑定,我能够让第二个 TextBlock 正确显示 TimeSpan,但我对这个解决方案并不太着迷。我希望第二个 TextBlock 随着时间的推移更新 TimeSpan。

例如,当用户加载应用程序时,第二个 TextBlock 会说“5 分钟”,但 15 分钟后,它仍然会说“5 分钟”,这是一种误导。

我能够找到这个解决方案(绑定到 DateTime.Now。更新值),这与我想要的非常接近,但并不完全在那里。

有什么办法可以将任务的开始时间传递给这个 Ticker 类并让文本自行更新?

编辑:这是我到目前为止所拥有的:
C#:
public class Ticker : INotifyPropertyChanged { public static DateTime StartTime { get; 放; }

    public Ticker()
    {
        Timer timer = new Timer();
        timer.Interval = 1000;
        timer.Elapsed += timer_Elapsed;
        timer.Start();
    }

    public string TimeDifference
    {
        get
        {
            string timetaken = "";
            try
            {
                TimeSpan ts = DateTime.Now - StartTime;
                timetaken = (StartTime == default(DateTime)) ? "StartTime not set!" : ((ts.Days * 24) + ts.Hours).ToString("N0") + " hours, " + ts.Minutes + " minutes, " + ts.Seconds + " seconds";
            }
            catch (Exception) { }

            return timetaken;
        }
    }

    private void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("TimeDifference"));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

XAML:
<StackPanel Grid.Row="2" Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="Dataset started on:"/>
<TextBlock Name="starttimeLabel" Text="10/23/2012 4:42:26 PM"/>
</StackPanel>
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
<TextBlock Text="Time taken:"/>
<TextBlock Name="timespanLabel" Text="{Binding Source={StaticResource ticker}, Path=TimeDifference, Mode=OneWay}"/>
</StackPanel>

最后,在我的 StatusPanel 的 Loaded 事件中,我有以下内容:
Ticker.StartTime = Convert.ToDateTime(starttimeLabel.Text);

我为糟糕的格式道歉,但我尝试按照说明无济于事(为代码块插入 4 个空格,然后尝试使用<code></code>等)

4

1 回答 1

0

尝试使用 DispatcherTimer "as" CountDown:

XAML:

<Window x:Class="CountDown.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
    <TextBlock x:Name="initialTime" Width="50" Height="20" Margin="165,66,288,224"></TextBlock>
    <TextBlock x:Name="txtCountDown" Width="50" Height="20" Margin="236,66,217,225"></TextBlock>
    </Grid>
</Window>

C#:

    namespace CountDown
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private DispatcherTimer cDown;

            public MainWindow()
            {
                InitializeComponent();
                initialTime.Text = DateTime.Now.ToString("HH:mm:ss");
                TimeSpan timeToDie = new TimeSpan(0, 0, 10); //Set the time "when the users load"
                txtCountDown.Text = timeToDie.ToString();

                cDown = new DispatcherTimer();
                cDown.Tick += new EventHandler(cDown_Tick);
                cDown.Interval = new TimeSpan(0, 0, 1);
                cDown.Start();
            }


            private void cDown_Tick(object sender, EventArgs e)
            {
                TimeSpan? dt = null;
                try
                {
                    dt = TimeSpan.Parse(txtCountDown.Text);
                    if (dt != null && dt.Value.TotalSeconds > 0  )
                    {
                        txtCountDown.Text = dt.Value.Add(new TimeSpan(0,0,-1)).ToString();
                    }
                    else 
                    {
                        cDown.Stop();
                    }
                }
                catch (Exception ex)
                {
                     cDown.Stop();
                     Console.WriteLine(ex.Message);
                }


            }

        }
    }
于 2012-10-28T00:21:22.817 回答