c# 将倒数计时器绑定到 Windows 应用商店应用中的文本框

本文关键字:应用 文本 Windows 倒数 计时器 绑定 | 更新日期: 2023-09-27 18:35:25

我对C#和一般编程相当陌生。

在上一个问题"C# 重置倒数计时器-调度程序计时器-"中,我得到了重置计时器的帮助。然后我尝试使我的代码更优雅,并尝试为计时器创建一个单独的类,并通过数据绑定更新倒计时文本块,而不是在 timer_Tick() 中硬编码此行中的 text 属性:

  Countdown.Text = (int)(duration - sw.Elapsed).TotalSeconds + " second(s)

我的问题是绑定失败。我仍然在与MVVM作斗争。这是我的代码:

倒计时计时器.cs

class CountDownTimer : DispatcherTimer
{
    public System.Diagnostics.Stopwatch sw { get; set; }
    static readonly TimeSpan duration = TimeSpan.FromSeconds(60);
    private int _seconds;
    public int Seconds
    {
        get { return _seconds; }
        set { _seconds = value; NotifyPropertyChanged("Seconds"); }
    }
    private string _timeElapsed;
    public string TimeElapsed
    {
        get { return _timeElapsed; }
        set { _timeElapsed = value; NotifyPropertyChanged("TimeElapsed"); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public void timer_Tick(object sender, object e)
    {
        if (sw.Elapsed <= duration)
        {
            Seconds = (int)(duration - sw.Elapsed).TotalSeconds;
            TimeElapsed = String.Format("{0} second(s)", Seconds);
        }
        else
        {
            TimeElapsed = "Times Up";
            this.Stop();
        }
    }
}

EquationView.xaml

 <StackPanel x:Name="timePanel" Orientation="Horizontal" Visibility="Collapsed">
            <TextBlock Text="Time Left: " Height="auto" 
                       Margin="20,10,5,10" FontSize="26"/>
            <TextBlock x:Name="countdown" Text="{Binding TimeElapsed}" 
                       Margin="20,10,20,10" Width="200"  
                       Height="auto" FontSize="26"/>
 </StackPanel>

EquationView.xaml.cs

public sealed partial class EquationView : Page
{
    //code
    private void startButton_Click(object sender, RoutedEventArgs e)
    {
        //more code
        // If level == difficult enable timer
        if (Level == PlayerModel.LevelEnum.Difficult)
        {
            // timer commands
            timer.sw = System.Diagnostics.Stopwatch.StartNew();
            timer.Interval = new TimeSpan(0, 0, 0, 1);
            timer.Tick += timer.timer_Tick;
            timer.Start();
            countdown.DataContext = timer;
     //more code
    } //end of method
    // much more code
} //end of class EquationView

我插入了行倒计时。文本 = 计时器。时间已过;试图找出出了什么问题,它给了我一个System.NullReferenceException。然后我把它改成了计时器。Seconds.ToString() 第一次显示 0,但之后返回 56 或 57。

附言我从我的 BindableBase 类中重新键入了属性更改方法,因为我现在不想处理多重继承。

c# 将倒数计时器绑定到 Windows 应用商店应用中的文本框

我更改了倒数计时器,看到这个问题:如何在 TextBlock 中显示更改时间?在我开始构建计时器之前,我已经看过了,但现在它对我的帮助更大。

倒计时计时器.cs

public class CountDownTimer :  BindableBase
{
    System.Diagnostics.Stopwatch sw;
    static readonly TimeSpan duration = TimeSpan.FromSeconds(60);
    private DispatcherTimer timer;
    public CountDownTimer() 
    {
        timer = new DispatcherTimer();
        sw = System.Diagnostics.Stopwatch.StartNew();
        timer.Interval = new TimeSpan(0, 0, 0, 1);
        timer.Tick += timer_Tick;
    }
    private int? _seconds;
    public int? Seconds
    {
        get { return _seconds; }
        set { _seconds = value; NotifyPropertyChanged("Seconds"); }
    }
    private string _timeElapsed;
    public string TimeElapsed
    {
        get { return _timeElapsed; }
        set { _timeElapsed = value; NotifyPropertyChanged("TimeElapsed"); }
    }

    public void timer_Tick(object sender, object e)
    {
        if (sw.Elapsed < duration)
        {
            Seconds = (int)(duration - sw.Elapsed).TotalSeconds;
            TimeElapsed = String.Format("{0} second(s)", Seconds);
        }
        else
        {
            TimeElapsed = "Times Up";
            timer.Stop();
        }
    }
   public void StartCountDown()
    {
        sw.Start();
        timer.Start();
    }
    public void StopCountDown()
    {
        timer.Stop();
        sw.Stop();
    }
}