You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF ListView中为每个按钮添加独立15分钟计时器的问题

WPF ListView按钮独立倒计时解决方案

原代码问题分析

  • 使用全局DispatcherTimer,所有按钮共享同一个计时器,点击新按钮会覆盖之前的计时器逻辑,导致旧按钮的计时中断
  • 每次Tick事件中都重置Timers_end = now.AddMinutes(15),相当于每次都重新开始15分钟倒计时,永远不会结束

解决思路

为每个按钮绑定独立的计时器和结束时间,用字典关联按钮实例与对应的计时信息,确保每个按钮的倒计时互不干扰。

实现代码

首先定义一个辅助类存储每个按钮的计时信息:

// 存储单个按钮的计时器和结束时间
private class TimerInfo
{
    public DispatcherTimer Timer { get; set; }
    public DateTime EndTime { get; set; }
}

// 字典:关联按钮与对应的计时信息
private readonly Dictionary<Button, TimerInfo> _buttonTimers = new Dictionary<Button, TimerInfo>();

修改按钮点击事件:

private void Button_ListView_Click(object sender, EventArgs e)
{
    var btn = sender as Button;
    if (btn == null) return;

    // 如果按钮已有计时器,直接返回(避免重复点击)
    if (_buttonTimers.ContainsKey(btn)) return;

    // 创建专属计时器和结束时间
    var endTime = DateTime.Now.AddMinutes(15);
    var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
    
    // 绑定Tick事件
    timer.Tick += (s, args) =>
    {
        var now = DateTime.Now;
        var remainingTime = endTime - now;

        if (remainingTime <= TimeSpan.Zero)
        {
            // 倒计时结束,更新按钮内容并清理资源
            btn.Content = "计时结束";
            timer.Stop();
            _buttonTimers.Remove(btn);
        }
        else
        {
            // 更新剩余时间显示
            btn.Content = remainingTime.ToString(@"hh\:mm\:ss");
        }
    };

    // 保存计时信息并启动计时器
    _buttonTimers.Add(btn, new TimerInfo { Timer = timer, EndTime = endTime });
    timer.Start();
}

额外注意事项

  • 若ListView存在动态加载/移除按钮的场景,记得在按钮被移除时,从字典中取出对应的计时器并停止,避免内存泄漏
  • 如果需要支持重复点击按钮重新计时,可以修改逻辑:若按钮已有计时器,先停止旧计时器再创建新的

内容的提问来源于stack exchange,提问作者Michał Schmude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:24:32