停止 DispatcherTimer 实例或更改其值
Stop a DispatcherTimer instance or change its value
我的应用程序是这样工作的:我选择过去的一个时间点,选择从该时间点开始的时间量 ("Within 3 hours..."),然后单击 "Add Timer"。这将创建一个新的堆栈面板,其中包括一个计时器,该计时器会倒计时从该时间点开始直到正好 x 小时为止还剩下多少时间。
在还剩 20、15 和 10 分钟时,它会播放提示音。
现在我的问题是,如果我单击生成的计时器旁边的 "Remove"(它会删除整个堆栈面板),倒计时仍然在后台运行,当它达到 20/15/10分钟它仍然发出声音。
我必须将那些删除的计时器重置为 0,或者停止它们,或者...我不确定如何完成此操作。我可能应该使用数据绑定,但我不确定我对它的理解是否足以在这里实现它。有人可以帮忙吗?
<Window x:Class="Alertimer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:Alertimer"
mc:Ignorable="d"
Title="Alertimer" SizeToContent="Height" Width="700" MinWidth="700" ResizeMode="CanMinimize">
<Window.Resources>
<Style TargetType="TextBox">
<Setter Property="Height" Value="25"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Name="Labels" Orientation="Horizontal">
<TextBox Text="Client" VerticalAlignment="Top" Margin="30,15,0,0" Width="130" Height="30" FontSize="12" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Ticket #" VerticalAlignment="Top" Margin="10,15,0,0" Width="80" Height="30" FontSize="12" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Time of last update" VerticalAlignment="Top" Margin="10,15,0,0" Width="180" Height="30" FontSize="12" FontStretch="Condensed" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Next update within?..." VerticalAlignment="Top" Margin="10,15,0,0" Width="125" Height="30" FontSize="12" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Add/Remove entry" VerticalAlignment="Top" Margin="10,15,0,0" Width="75" Height="30" FontSize="10" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
</StackPanel>
<StackPanel Name="Column" Orientation="Vertical" Margin="0,0,0,30">
<StackPanel Name="Controls" Orientation="Horizontal" Margin="0,0,0,5">
<TextBox Name="Client" Margin="30,50,0,0" Text="LSC Communications" GotFocus="TextBox_GotFocus" Width="130" FontSize="11" VerticalContentAlignment="Center"/>
<TextBox Name="Ticket" Margin="10,50,0,0" Text="INC0123456" GotFocus="TextBox_GotFocus" Width="80" FontSize="11" VerticalContentAlignment="Center"/>
<xctk:DateTimePicker Name="LastUpdate" Height="25" Width="180" Margin="10,50,0,0" DisplayDefaultValueOnEmptyText="True" Format="Custom" FormatString="dd MMMM HH:mm tt" TimePickerShowButtonSpinner="False"></xctk:DateTimePicker>
<ComboBox Name="Within" SelectedValuePath="Content" IsEditable="True" IsReadOnly="True" Text="Select time period" Margin="10,50,0,0" Width="125" Height="25" VerticalContentAlignment="Center">
<ComboBoxItem Content="Within 1 hour"/>
<ComboBoxItem Content="Within 2 hours"/>
<ComboBoxItem Content="Within 3 hours"/>
<ComboBoxItem Content="Within 4 hours"/>
<ComboBoxItem Content="Within 5 hours"/>
<ComboBoxItem Content="Within 6 hours"/>
</ComboBox>
<Button Name="Timer" Content="Add timer" Click="addNewTimer" Margin="10,50,0,0" Width="75" FontSize="11" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Globalization;
using Xceed.Wpf.Toolkit;
namespace Alertimer
{
public partial class MainWindow : Window
{
DispatcherTimer _timer;
System.Media.SoundPlayer warning;
public MainWindow()
{
InitializeComponent();
}
public void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Text = string.Empty;
tb.GotFocus -= TextBox_GotFocus;
}
private void addNewTimer(object sender, EventArgs e)
{
Button Timer = sender as Button;
StackPanel stkButtonParent = Timer.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
StackPanel newRow = NewRow();
stkCover.Children.Add(newRow);
}
private StackPanel NewRow() {
double hoursWithin = 0;
switch (Within.SelectedValue)
{
case "Within 1 hour":
hoursWithin = 1;
break;
case "Within 2 hours":
hoursWithin = 2;
break;
case "Within 3 hours":
hoursWithin = 3;
break;
case "Within 4 hours":
hoursWithin = 4;
break;
case "Within 5 hours":
hoursWithin = 5;
break;
case "Within 6 hours":
hoursWithin = 6;
break;
}
StackPanel newAlert = new StackPanel();
newAlert.Orientation = Orientation.Horizontal;
newAlert.Margin = new Thickness(0, 5, 0, 0);
TextBox NewClient = new TextBox();
NewClient.Text = Client.Text;
NewClient.Width = 130;
NewClient.Margin = new Thickness(30, 0, 0, 0);
NewClient.Style = (Style)Application.Current.Resources["TextBoxes"];
NewClient.IsEnabled = false;
TextBox NewTicket = new TextBox();
NewTicket.Text = Ticket.Text;
NewTicket.Width = 80;
NewTicket.Margin = new Thickness(10,0,0,0);
NewTicket.Style = (Style)Application.Current.Resources["TextBoxes"];
NewTicket.IsEnabled = false;
try
{
DateTime nextTimeTest = DateTime.ParseExact(LastUpdate.Text, "dd MMMM HH:mm tt", CultureInfo.InvariantCulture).AddHours(hoursWithin);
}
catch (Exception)
{
System.Windows.MessageBox.Show("You forgot to input the time of the last update!", "Whoops!", MessageBoxButton.OK, MessageBoxImage.Warning);
}
DateTime nextTime = DateTime.ParseExact(LastUpdate.Text, "dd MMMM HH:mm tt", CultureInfo.InvariantCulture).AddHours(hoursWithin);
String Today = DateTime.Now.ToString("dd MMMM HH:mm tt");
DateTime currentTime = DateTime.ParseExact(Today,"dd MMMM HH:mm tt", CultureInfo.InvariantCulture);
TimeSpan timeLeft = nextTime - currentTime;
string[] timeLeftElements = timeLeft.ToString().Split(':');
int hours = Convert.ToInt32(timeLeftElements[0]);
int minutes = Convert.ToInt32(timeLeftElements[1]);
int seconds = Convert.ToInt32(timeLeftElements[2]);
TextBox TillNextUpdate = new TextBox();
TillNextUpdate.Margin = new Thickness(10, 0, 0, 0);
TillNextUpdate.Width = 315;
TillNextUpdate.Style = (Style)Application.Current.Resources["TextBoxes"];
TillNextUpdate.FontSize = 16;
TillNextUpdate.Name = "timeLeft";
Button NewRowDelete = new Button();
NewRowDelete.Content = "Remove";
NewRowDelete.Width = 75;
NewRowDelete.Height = 25;
NewRowDelete.Margin = new Thickness(10, 0, 0, 0);
NewRowDelete.Click += RemoveTimer;
newAlert.Children.Add(NewClient);
newAlert.Children.Add(NewTicket);
newAlert.Children.Add(TillNextUpdate);
newAlert.Children.Add(NewRowDelete);
timeLeft = new TimeSpan(hours, minutes, seconds);
_timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
TillNextUpdate.Text = timeLeft.ToString("c");
if (timeLeft == TimeSpan.Zero)
{
_timer.Stop();
}
else
{
timeLeft = timeLeft.Add(TimeSpan.FromSeconds(-1));
}
if (TillNextUpdate.Text == "00:20:00")
{
TillNextUpdate.Background = Brushes.Yellow;
warning = new System.Media.SoundPlayer(Properties.Resources.alert20);
warning.Play();
}
else if (TillNextUpdate.Text == "00:15:00")
{
TillNextUpdate.Background = Brushes.Orange;
TillNextUpdate.FontWeight = FontWeights.Bold;
warning = new System.Media.SoundPlayer(Properties.Resources.alert15);
warning.Play();
}
else if (TillNextUpdate.Text == "00:10:00")
{
TillNextUpdate.Background = Brushes.Red;
warning = new System.Media.SoundPlayer(Properties.Resources.alert10);
warning.Play();
}
}, Application.Current.Dispatcher);
_timer.Start();
Frame.MinHeight = Frame.MinHeight + 25;
return newAlert;
}
private void RemoveTimer(object sender, EventArgs e)
{
Button Delete = sender as Button;
StackPanel stkButtonParent = Delete.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
stkCover.Children.Remove(stkButtonParent);
Frame.MinHeight = Frame.MinHeight - 25;
}
}
}
您需要存储 DispatcherTimer。在 NewRow() 方法中,
_timer.Start();
newAlert.Tag = _timer; // store _timer !
Frame.MinHeight = Frame.MinHeight + 25;
return newAlert;
在 RemoveTimer 方法中,获取定时器并停止()
private void RemoveTimer(object sender, EventArgs e)
{
Button Delete = sender as Button;
StackPanel stkButtonParent = Delete.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
DispatcherTimer timer = stkButtonParent.Tag as DispatcherTimer;
timer.Stop(); // stop timer
stkCover.Children.Remove(stkButtonParent);
Frame.MinHeight = Frame.MinHeight - 25;
}
祝你好运!
我的应用程序是这样工作的:我选择过去的一个时间点,选择从该时间点开始的时间量 ("Within 3 hours..."),然后单击 "Add Timer"。这将创建一个新的堆栈面板,其中包括一个计时器,该计时器会倒计时从该时间点开始直到正好 x 小时为止还剩下多少时间。
在还剩 20、15 和 10 分钟时,它会播放提示音。
现在我的问题是,如果我单击生成的计时器旁边的 "Remove"(它会删除整个堆栈面板),倒计时仍然在后台运行,当它达到 20/15/10分钟它仍然发出声音。
我必须将那些删除的计时器重置为 0,或者停止它们,或者...我不确定如何完成此操作。我可能应该使用数据绑定,但我不确定我对它的理解是否足以在这里实现它。有人可以帮忙吗?
<Window x:Class="Alertimer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:Alertimer"
mc:Ignorable="d"
Title="Alertimer" SizeToContent="Height" Width="700" MinWidth="700" ResizeMode="CanMinimize">
<Window.Resources>
<Style TargetType="TextBox">
<Setter Property="Height" Value="25"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Name="Labels" Orientation="Horizontal">
<TextBox Text="Client" VerticalAlignment="Top" Margin="30,15,0,0" Width="130" Height="30" FontSize="12" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Ticket #" VerticalAlignment="Top" Margin="10,15,0,0" Width="80" Height="30" FontSize="12" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Time of last update" VerticalAlignment="Top" Margin="10,15,0,0" Width="180" Height="30" FontSize="12" FontStretch="Condensed" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Next update within?..." VerticalAlignment="Top" Margin="10,15,0,0" Width="125" Height="30" FontSize="12" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
<TextBox Text="Add/Remove entry" VerticalAlignment="Top" Margin="10,15,0,0" Width="75" Height="30" FontSize="10" VerticalContentAlignment="Center" BorderBrush="{x:Null}" TextWrapping="Wrap" IsEnabled="False"/>
</StackPanel>
<StackPanel Name="Column" Orientation="Vertical" Margin="0,0,0,30">
<StackPanel Name="Controls" Orientation="Horizontal" Margin="0,0,0,5">
<TextBox Name="Client" Margin="30,50,0,0" Text="LSC Communications" GotFocus="TextBox_GotFocus" Width="130" FontSize="11" VerticalContentAlignment="Center"/>
<TextBox Name="Ticket" Margin="10,50,0,0" Text="INC0123456" GotFocus="TextBox_GotFocus" Width="80" FontSize="11" VerticalContentAlignment="Center"/>
<xctk:DateTimePicker Name="LastUpdate" Height="25" Width="180" Margin="10,50,0,0" DisplayDefaultValueOnEmptyText="True" Format="Custom" FormatString="dd MMMM HH:mm tt" TimePickerShowButtonSpinner="False"></xctk:DateTimePicker>
<ComboBox Name="Within" SelectedValuePath="Content" IsEditable="True" IsReadOnly="True" Text="Select time period" Margin="10,50,0,0" Width="125" Height="25" VerticalContentAlignment="Center">
<ComboBoxItem Content="Within 1 hour"/>
<ComboBoxItem Content="Within 2 hours"/>
<ComboBoxItem Content="Within 3 hours"/>
<ComboBoxItem Content="Within 4 hours"/>
<ComboBoxItem Content="Within 5 hours"/>
<ComboBoxItem Content="Within 6 hours"/>
</ComboBox>
<Button Name="Timer" Content="Add timer" Click="addNewTimer" Margin="10,50,0,0" Width="75" FontSize="11" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Globalization;
using Xceed.Wpf.Toolkit;
namespace Alertimer
{
public partial class MainWindow : Window
{
DispatcherTimer _timer;
System.Media.SoundPlayer warning;
public MainWindow()
{
InitializeComponent();
}
public void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Text = string.Empty;
tb.GotFocus -= TextBox_GotFocus;
}
private void addNewTimer(object sender, EventArgs e)
{
Button Timer = sender as Button;
StackPanel stkButtonParent = Timer.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
StackPanel newRow = NewRow();
stkCover.Children.Add(newRow);
}
private StackPanel NewRow() {
double hoursWithin = 0;
switch (Within.SelectedValue)
{
case "Within 1 hour":
hoursWithin = 1;
break;
case "Within 2 hours":
hoursWithin = 2;
break;
case "Within 3 hours":
hoursWithin = 3;
break;
case "Within 4 hours":
hoursWithin = 4;
break;
case "Within 5 hours":
hoursWithin = 5;
break;
case "Within 6 hours":
hoursWithin = 6;
break;
}
StackPanel newAlert = new StackPanel();
newAlert.Orientation = Orientation.Horizontal;
newAlert.Margin = new Thickness(0, 5, 0, 0);
TextBox NewClient = new TextBox();
NewClient.Text = Client.Text;
NewClient.Width = 130;
NewClient.Margin = new Thickness(30, 0, 0, 0);
NewClient.Style = (Style)Application.Current.Resources["TextBoxes"];
NewClient.IsEnabled = false;
TextBox NewTicket = new TextBox();
NewTicket.Text = Ticket.Text;
NewTicket.Width = 80;
NewTicket.Margin = new Thickness(10,0,0,0);
NewTicket.Style = (Style)Application.Current.Resources["TextBoxes"];
NewTicket.IsEnabled = false;
try
{
DateTime nextTimeTest = DateTime.ParseExact(LastUpdate.Text, "dd MMMM HH:mm tt", CultureInfo.InvariantCulture).AddHours(hoursWithin);
}
catch (Exception)
{
System.Windows.MessageBox.Show("You forgot to input the time of the last update!", "Whoops!", MessageBoxButton.OK, MessageBoxImage.Warning);
}
DateTime nextTime = DateTime.ParseExact(LastUpdate.Text, "dd MMMM HH:mm tt", CultureInfo.InvariantCulture).AddHours(hoursWithin);
String Today = DateTime.Now.ToString("dd MMMM HH:mm tt");
DateTime currentTime = DateTime.ParseExact(Today,"dd MMMM HH:mm tt", CultureInfo.InvariantCulture);
TimeSpan timeLeft = nextTime - currentTime;
string[] timeLeftElements = timeLeft.ToString().Split(':');
int hours = Convert.ToInt32(timeLeftElements[0]);
int minutes = Convert.ToInt32(timeLeftElements[1]);
int seconds = Convert.ToInt32(timeLeftElements[2]);
TextBox TillNextUpdate = new TextBox();
TillNextUpdate.Margin = new Thickness(10, 0, 0, 0);
TillNextUpdate.Width = 315;
TillNextUpdate.Style = (Style)Application.Current.Resources["TextBoxes"];
TillNextUpdate.FontSize = 16;
TillNextUpdate.Name = "timeLeft";
Button NewRowDelete = new Button();
NewRowDelete.Content = "Remove";
NewRowDelete.Width = 75;
NewRowDelete.Height = 25;
NewRowDelete.Margin = new Thickness(10, 0, 0, 0);
NewRowDelete.Click += RemoveTimer;
newAlert.Children.Add(NewClient);
newAlert.Children.Add(NewTicket);
newAlert.Children.Add(TillNextUpdate);
newAlert.Children.Add(NewRowDelete);
timeLeft = new TimeSpan(hours, minutes, seconds);
_timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
TillNextUpdate.Text = timeLeft.ToString("c");
if (timeLeft == TimeSpan.Zero)
{
_timer.Stop();
}
else
{
timeLeft = timeLeft.Add(TimeSpan.FromSeconds(-1));
}
if (TillNextUpdate.Text == "00:20:00")
{
TillNextUpdate.Background = Brushes.Yellow;
warning = new System.Media.SoundPlayer(Properties.Resources.alert20);
warning.Play();
}
else if (TillNextUpdate.Text == "00:15:00")
{
TillNextUpdate.Background = Brushes.Orange;
TillNextUpdate.FontWeight = FontWeights.Bold;
warning = new System.Media.SoundPlayer(Properties.Resources.alert15);
warning.Play();
}
else if (TillNextUpdate.Text == "00:10:00")
{
TillNextUpdate.Background = Brushes.Red;
warning = new System.Media.SoundPlayer(Properties.Resources.alert10);
warning.Play();
}
}, Application.Current.Dispatcher);
_timer.Start();
Frame.MinHeight = Frame.MinHeight + 25;
return newAlert;
}
private void RemoveTimer(object sender, EventArgs e)
{
Button Delete = sender as Button;
StackPanel stkButtonParent = Delete.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
stkCover.Children.Remove(stkButtonParent);
Frame.MinHeight = Frame.MinHeight - 25;
}
}
}
您需要存储 DispatcherTimer。在 NewRow() 方法中,
_timer.Start();
newAlert.Tag = _timer; // store _timer !
Frame.MinHeight = Frame.MinHeight + 25;
return newAlert;
在 RemoveTimer 方法中,获取定时器并停止()
private void RemoveTimer(object sender, EventArgs e)
{
Button Delete = sender as Button;
StackPanel stkButtonParent = Delete.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
DispatcherTimer timer = stkButtonParent.Tag as DispatcherTimer;
timer.Stop(); // stop timer
stkCover.Children.Remove(stkButtonParent);
Frame.MinHeight = Frame.MinHeight - 25;
}
祝你好运!