单击按钮停止DispatcherTimer

时间:2019-05-01 15:16:06

标签: c# wpf button dispatchertimer

当我单击“停止”按钮时,即使我告诉它停止,计时器仍在倒计时。

我当前的相关代码:

我在这里命名计时器,因为我也需要访问它们才能使用“停止/全部启动”按钮。

namespace Row_Interface
{
    public partial class MainWindow : Window
    {
        //Declare the timers here, so the stop all button can access them as well
        DispatcherTimer motorTimer_1 = new DispatcherTimer();
        TimeSpan motorCycleTime_1 = TimeSpan.FromSeconds(0);

当我单击on按钮时,IndividualTestStart方法被调用并传递了相关参数:

public void motorOnBtn_1_Click(object sender, RoutedEventArgs e)
        {
            IndividualTestStart(motorOnBtn_1, motorOffBtn_1, motorTimer_1, motorCycleTime_1, timeUntilmotorCycle_1, motorTestCycles_1);
        }

当我单击关闭按钮时,我想停止该计时器,以使循环永远不会结束:

        private void motorOffBtn_1_Click(object sender, RoutedEventArgs e)
        {
            motorTimer_1.Stop();
            motorOnBtn_1.IsEnabled = true; //Enables the start test button
            motorOffBtn_1.IsEnabled = false; //Disables the stop test button

        }

当我单击开始时,这称为。最终,我将在“停止”按钮上看到类似的内容,但我一次只迈出了一步:

private void IndividualTestStart(Button startButton, Button stopButton, DispatcherTimer dispatcherTimer, TimeSpan timeSpan, TextBox timeRemaining, TextBox cycleCount)
        {
            stopButton.IsEnabled = true; //Enables the stop button

            //Set the time to run. This will be set from the database eventually.
            timeSpan = TimeSpan.FromSeconds(10);

            //Set up the new timer. Updated every second.
            dispatcherTimer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
            {
                timeRemaining.Text = timeSpan.ToString("c"); //Sets the text in the textbox to the time remaining in the timer
                startButton.IsEnabled = false; //Disables the start test button once the test is started
                if (timeSpan == TimeSpan.Zero) //Checks to seee if the time has run out
                {
                    dispatcherTimer.Stop(); //Stops the timer once the time has run out
                    startButton.IsEnabled = true; //Enables the start test button
                    int initialCycleCount = 0;
                    initialCycleCount++;
                    cycleCount.Text = initialCycleCount.ToString();
                    stopButton.IsEnabled = false;//Disables the stop button

                }
                timeSpan = timeSpan.Add(TimeSpan.FromSeconds(-1)); //Subtracts one second each time the timer "ticks"
            }, Application.Current.Dispatcher);  //runs within the UI thread

            dispatcherTimer.Start(); //Starts the timer 
        }
}

单击停止按钮时,我希望文本框中的计时器停止倒计时。但是,它一直在滴答作响。当我单击停止时,重新启用了开始按钮,因此我知道它正在触发事件处理程序中的代码。但这并没有停止计时器。

现在不启动新计时器。 新代码:

        public void motorOnBtn_1_Click(object sender, RoutedEventArgs e)
        {
            IndividualTestStart(motorOnBtn_1, motorOffBtn_1, motorTimer_1, motorCycleTime_1, timeUntilmotorCycle_1, motorTestCycles_1);
        }

        private void IndividualTestStart(Button startButton, Button stopButton, DispatcherTimer dispatcherTimer, TimeSpan timeSpan, TextBox timeRemaining, TextBox cycleCount)
        {
            stopButton.IsEnabled = true; //Enables the stop button

            //Set the time to run. This will be set from the database eventually.
            timeSpan = TimeSpan.FromSeconds(10);

            {
                timeRemaining.Text = timeSpan.ToString("c"); //Sets the text in the textbox to the time remaining in the timer
                startButton.IsEnabled = false; //Disables the start test button once the test is started
                if (timeSpan == TimeSpan.Zero) //Checks to seee if the time has run out
                {
                    dispatcherTimer.Stop(); //Stops the timer once the time has run out
                    startButton.IsEnabled = true; //Enables the start test button
                    int initialCycleCount = 0;
                    initialCycleCount++;
                    cycleCount.Text = initialCycleCount.ToString();
                    stopButton.IsEnabled = false;//Disables the stop button

                }
                timeSpan = timeSpan.Add(TimeSpan.FromSeconds(-1)); //Subtracts one second each time the timer "ticks"
            };  //runs within the UI thread

            dispatcherTimer.Start(); //Starts the timer 
        }

1 个答案:

答案 0 :(得分:1)

代码中的问题是,您用motorTimer_1初始化了DispatcherTimer,而motorTimer_1并没有执行任何操作,然后您将dispatcherTimer作为DispatcherTimer参数传入,并且然后用新创建的不同motorTimer_1替换参数的值。

新计时器可以正常工作,但是当您在DispatcherTimer上调用stop时,什么也没有发生,因为那不是正在运行的计时器。您可以简单地将新的motorTimer_1直接分配给IndividualTestStart()中的IndividualTestStart(),但是在DispatcherTimer中对所有参数进行参数化非常麻烦,因此它可以与不同的DispatcherTimers一起使用。

我们将执行以下操作:没有理由传递IndividualTestStart()DispatcherTimer必须创建private DispatcherTimer IndividualTestStart(Button startButton, Button stopButton, TimeSpan timeSpan, TextBox timeRemaining, TextBox cycleCount) { stopButton.IsEnabled = true; //Enables the stop button //Set the time to run. This will be set from the database eventually. timeSpan = TimeSpan.FromSeconds(10); // Set up the new timer. Updated every second. var dispatcherTimer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate { timeRemaining.Text = timeSpan.ToString("c"); //Sets the text in the textbox to the time remaining in the timer startButton.IsEnabled = false; //Disables the start test button once the test is started if (timeSpan == TimeSpan.Zero) //Checks to seee if the time has run out { dispatcherTimer.Stop(); //Stops the timer once the time has run out startButton.IsEnabled = true; //Enables the start test button int initialCycleCount = 0; initialCycleCount++; cycleCount.Text = initialCycleCount.ToString(); stopButton.IsEnabled = false;//Disables the stop button } timeSpan = timeSpan.Add(TimeSpan.FromSeconds(-1)); //Subtracts one second each time the timer "ticks" }, Application.Current.Dispatcher); //runs within the UI thread dispatcherTimer.Start(); //Starts the timer return dispatcherTimer; } public void motorOnBtn_1_Click(object sender, RoutedEventArgs e) { if (motorTimer_1 == null) { // Create/initialize a new timer and assign it to motorTimer_1 motorTimer_1 = IndividualTestStart(motorOnBtn_1, motorOffBtn_1, motorCycleTime_1, timeUntilmotorCycle_1, motorTestCycles_1); } else { // It's already there, just start it. motorTimer_1.Start(); } } 才能对其进行初始化。好的,让我们开始吧。它将创建一个新文件并返回它。

TimerThing

由于这是WPF,所以您将要编写一个拥有DispatcherTimer,两个用于启动和停止它的命令以及一个公共bool属性的视图模型类ObservableCollection<TimerThing>(以更好的名称命名)是否正在运行。 IndividualTestStart()应该是该类的方法。父视图模型将具有一个TimerThing,其中包含任意数量的products: any[] = [{ product_id: "2", product_name: "Drinks" }, { product_id: "3", product_name: "Wafers" }, { product_id: "4", product_name: "Chocolates" } ]; productIDToSearch:number = 4; quantityToAdd: number = 20; let foundIndex = products.findIndex((val) => val.product_id == productIDToSearch); if(this.foundIndex >= 0) { this.products[this.foundIndex].quantity = this.quantityToAdd; } else { this.products.push({product_id:productIDToSearch, product_name:'Ice-cream', quantityToAdd: 33}); console.log(products); } ,这些元素将显示在具有ItemTemplate的ItemsControl中,该ItemTemplate创建绑定到Start和Stop命令的按钮。上面的代码看起来会非常不同,因为C#代码中的任何一个都不了解按钮:相反,项目模板XAML中的按钮将通过绑定启用/禁用。