转眼又是一年,作为开年的第一篇博客,先写点简单的热热手,毕竟也好久没写了。
如题,这是一篇实战类型的文章,之所以放到“多线程开发”这个系列来呢,是因为…Emmmm,没有理由,就是想放这(任性**_**)。
进入正题>>>
在日常开发中,会遇到如下一些情况:
①按钮点击后隔一段时间方可再次点击,如:发送验证码
②按钮加载后隔一段时间方可点击,如:阅读条款后已同意按钮
③按钮点击后隔一段时间才会触发事件,如:点击查询按钮后指定时间无响应则主动结束
针对①②两种情况,我们可以联合起来分析,如在Click事件或Load事件触发后禁用按钮一段时间即可。这段代码非常简单,非常符合此篇博客的主题。
public async void DelayToEnable(int milliseconds)
{
this.IsEnabled = false;
await Task.Delay(milliseconds);
this.IsEnabled = true;
}
针对第③种情况,原本也可以用以上方法进行稍作调整来实现,但为了体现封装性,也方便日后使用,所以还是继承Button重写了一些东西。
public class DelayButton : System.Windows.Controls.Button
{
/// <summary>
/// 延时启用
/// </summary>
/// <param name="milliseconds"></param>
public async void DelayToEnable(int milliseconds)
{
this.IsEnabled = false;
await Task.Delay(milliseconds);
this.IsEnabled = true;
}
/// <summary>
/// 取消延时触发的令牌
/// </summary>
private CancellationTokenSource m_DelayTriggerCts;
/// <summary>
/// 延时触发间隔,单位(ms)
/// </summary>
public int DelayTriggerInterval
{
get { return (int)GetValue(DelayTriggerIntervalProperty); }
set { SetValue(DelayTriggerIntervalProperty, value); }
}
// Using a DependencyProperty as the backing store for DelayTriggerInterval. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DelayTriggerIntervalProperty =
DependencyProperty.Register(nameof(DelayTriggerInterval), typeof(int), typeof(DelayButton), new PropertyMetadata(0));
/// <summary>
/// 延时触发路由事件
/// </summary>
public static readonly RoutedEvent DelayTriggerRoutedEvent =
EventManager.RegisterRoutedEvent("DelayTrigger", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(DelayButton));
public event RoutedEventHandler DelayTrigger
{
add { this.AddHandler(DelayTriggerRoutedEvent, value); }
remove { this.RemoveHandler(DelayTriggerRoutedEvent, value); }
}
/// <summary>
/// 取消延时触发
/// </summary>
public void CancelDelayTrigger()
{
m_DelayTriggerCts?.Cancel();
}
protected override async void OnClick()
{
base.OnClick();
try
{
m_DelayTriggerCts = new CancellationTokenSource();
await Task.Delay(DelayTriggerInterval, m_DelayTriggerCts.Token);
RoutedEventArgs args = new RoutedEventArgs(DelayTriggerRoutedEvent, this);
this.RaiseEvent(args);
}
catch (Exception)
{
Console.WriteLine("The delay trigger has been cancelled.");
}
finally
{
m_DelayTriggerCts.Dispose();
m_DelayTriggerCts = null;
}
}
}
(增加一个可以手动取消延迟的令牌,可以在长时间的延迟等待过程中随时结束)