我正在编写一个显示特定耗时任务状态的WPF应用程序。
我有一个TextBlock绑定到任务的开始时间,我有另一个TextBlock,用于显示在所述任务上花费的时间。
使用与转换器的简单绑定,我能够让第二个TextBlock正确显示TimeSpan,但我对这个解决方案并不是太疯狂。我希望第二个TextBlock能够随着时间的推移更新TimeSpan。
例如,当用户加载应用程序时,第二个TextBlock会说“5分钟”,但15分钟后,仍会说“5分钟”,这会产生误导。
我能够找到这个解决方案(Binding to DateTime.Now. Update the value),这种解决方案非常接近我想要的,但并不完全在那里。
有什么方法可以将任务的开始时间传递给此Ticker类并让文本自行更新?
编辑:这是我到目前为止所做的:
C#:
公共类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>
等)。
答案 0 :(得分:0)
尝试使用DispatcherTimer“作为”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);
}
}
}
}