VB.Net开发Windows 10定时通知提醒功能相关问题咨询
解决方案
核心问题
你当前的代码将通知弹出逻辑直接写在了提醒设置按钮的点击事件末尾,所以每次点击保存都会立刻触发通知,没有按指定时间校验的逻辑。
调整步骤
- 首先给Access的
TblReminder表新增一个IsTriggered字段,类型为是/否(布尔型),默认值设为False,用于标记提醒是否已经触发,避免重复弹出通知。 - 配置窗体上的
Timer1组件,将其Interval属性设为60000(即每60秒检查一次到期提醒,可根据需求调整精度)。 - 修正插入数据时的参数错误,将
ReminderDate字段以日期类型存储,避免后续时间比较出错。 - 删除按钮点击事件里直接弹出通知的代码,新增Timer的Tick事件用于定时检查到期提醒。
- 新增通知点击事件处理,点击后打开详情窗体传递对应提醒ID。
调整后完整代码
Imports System.Data.OleDb Public Class frmReminder Private CurrentReminderID As Integer = -1 ' 存储待查看的提醒ID,用于通知点击后传递到详情页 Private PendingDetailID As Integer = -1 Private Sub frmReminder_Load(sender As Object, e As EventArgs) Handles MyBase.Load BtnClear.PerformClick() Timer1.Enabled = True End Sub Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click Label6.Text = "" TxtCustName.Text = "" TxtDeviceInfo.Text = "" TxtPrice.Text = "" TxtDateDue.ResetText() CurrentReminderID = -1 End Sub Private Sub BtnSetReminder_Click(sender As Object, e As EventArgs) Handles BtnSetReminder.Click If DbConnect() Then Dim SQLCmd As New OleDbCommand If CurrentReminderID = -1 Then With SQLCmd .Connection = cn .CommandText = "Insert into TblReminder (CustomerName, DeviceInfo, RepairPrice, ReminderDate, IsTriggered)" & _ "Values (@CustomerName, @DeviceInfo, @RepairPrice, @ReminderDate, @IsTriggered)" .Parameters.AddWithValue("@CustomerName", TxtCustName.Text) .Parameters.AddWithValue("@DeviceInfo", TxtDeviceInfo.Text) .Parameters.AddWithValue("@RepairPrice", TxtPrice.Text) ' 转换为日期类型存储,去掉参数名前多余的空格 .Parameters.AddWithValue("@ReminderDate", DateTime.Parse(TxtDateDue.Text)) .Parameters.AddWithValue("@IsTriggered", False) .ExecuteNonQuery() .CommandText = "Select @@Identity" CurrentReminderID = .ExecuteScalar Label6.Text = CurrentReminderID End With End If cn.Close() End If ' 删掉原来直接弹出通知的代码 End Sub ' 新增Timer定时检查事件 Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick If DbConnect() Then Dim SQLCmd As New OleDbCommand With SQLCmd .Connection = cn ' 查询所有已到时间且未触发的提醒 .CommandText = "Select * from TblReminder where ReminderDate <= @NowTime And IsTriggered = False" .Parameters.AddWithValue("@NowTime", DateTime.Now) Dim reader As OleDbDataReader = .ExecuteReader() While reader.Read() Dim rid As Integer = reader("ReminderID") Dim custName As String = reader("CustomerName").ToString() ' 弹出通知 Notification.ShowBalloonTip(1000, "客户订单到期提醒", $"客户 {custName} 的订单已到期", ToolTipIcon.Info) ' 存储当前触发的提醒ID PendingDetailID = rid ' 更新标记为已触发 Dim updateCmd As New OleDbCommand updateCmd.Connection = cn updateCmd.CommandText = "Update TblReminder set IsTriggered = True where ReminderID = @RID" updateCmd.Parameters.AddWithValue("@RID", rid) updateCmd.ExecuteNonQuery() End While reader.Close() End With cn.Close() End If End Sub ' 新增通知点击事件处理 Private Sub Notification_BalloonTipClicked(sender As Object, e As EventArgs) Handles Notification.BalloonTipClicked If PendingDetailID > 0 Then ' 打开详情窗体,将提醒ID传递过去,可根据自己的详情窗体逻辑调整 Dim detailForm As New frmReminderDetail(PendingDetailID) detailForm.Show() PendingDetailID = -1 End If End Sub End Class
补充说明
- 如果需要更高的触发精度,可以将Timer的Interval调小到10000(10秒),但不建议低于1秒,避免频繁查询数据库影响性能。
- 时间比较时默认用的是系统本地时间,如果你的业务涉及时区,需要统一用UTC时间存储和比较。
- 程序重启后依然会自动检查所有未触发的到期提醒,不会丢失之前设置的任务。
内容的提问来源于stack exchange,提问作者Yousaer10
相关产品推荐
相关产品推荐

