如何将变量传递给WPF绑定?

时间:2012-10-27 19:07:28

标签: c# wpf binding

我正在编写一个显示特定耗时任务状态的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>等)。

1 个答案:

答案 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);
                }


            }

        }
    }