【问题标题】:Scheduled Notifications in Windows 10 VB.NetWindows 10 VB.Net 中的计划通知
【发布时间】:2021-12-08 02:33:00
【问题描述】:

我正在做一个项目,用户设置一个提醒,其中包含信息、日期和时间,以便弹出通知,并且通知应该是可点击的,并打开另一个带有提醒信息的表单。到目前为止,我可以设置提醒,但它会在点击提醒按钮后立即弹出,我的通知看起来是标准的 Windows 10 通知,我只想将通知安排在某个日期和时间。包括日期和时间在内的信息被保存到 Access 数据库中。我正在使用 VB.Net

亲切的问候

表格:

This is my reminder form as of now

This is how my notification looks like

    Imports System.Data.OleDb

Public Class frmReminder

    Private CurrentReminderID 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()
    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)"
                    .CommandText &= "Values (@CustomerName, @DeviceInfo, @RepairPrice, @ReminderDate)"
                    .Parameters.AddWithValue("@CustomerName", TxtCustName.Text)
                    .Parameters.AddWithValue("@DeviceInfo", TxtDeviceInfo.Text)
                    .Parameters.AddWithValue("@RepairPrice", TxtPrice.Text)
                    .Parameters.AddWithValue(" @ReminderDate", TxtDateDue.Text)
                    .ExecuteNonQuery()

                    .CommandText = "Select @@Identity"
                    CurrentReminderID = .ExecuteScalar
                    Label6.Text = CurrentReminderID
                End With
            End If
        End If
        Notification.ShowBalloonTip(1000, "Reminder", "Customer Order Due!", ToolTipIcon.None)
    End Sub

End Class

【问题讨论】:

    标签: vb.net push-notification windows-10 scheduled-tasks reminders


    【解决方案1】:

    您需要使用计时器,并且为了避免不断读取数据库,您可以使用非常简单的东西,例如 DateTimePicker 或 TextBox。在本例中,我将使用 Texbox。

    因此,在您的表单中插入一个 TextBox1 并具有第一个日期/时间的值(从您的数据库中读取一次)。 Textbox1 文本应类似于“2021-10-21 15:00”(不要输入秒数,也不要忘记在日期和时间之间留一个空格)

    TextBox1.Text="2021-10-21 15:00" ' read this data from your database 
    

    然后您需要在表单中插入一个 Timer 并添加以下值:

    Timer1.Interval = 60000 ' 1 minute
    Timer1.Enabled = True
    

    最后,您需要双击 Timer1 并编写以下代码:

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        If TextBox1.Text = Now.ToString("yyyy-MM-dd HH:mm") Then 
           ' At this moment you should read the next date/time and put that in TextBox1
           MsgBox("Show the popup notification") 
        End If
    End Sub
    

    【讨论】:

      【解决方案2】:

      由于您使用的是数据库连接,因此假设您熟悉多线程。

      规则 1. 最简单的方法是让您的应用程序跟踪(在 RAM 中)下一个通知。任何时候你通过你的应用程序添加一个新的,它都会将它插入到数据库中,并检查它是否会在 RAM 中的当前一个之前消失。当 RAM 中的一个过期时,它会从 DB 中获取下一个。总而言之,您可以找到一种方法来确保在任何给定时间将下一个经过的时间保存在 RAM 中。

      规则 2。然后,当通知“保存”在 RAM 中时,比较应该显示通知的时间 - 当前时间,这将告诉您通知应该显示多长时间,并为该时间设置一个计时器时间。

      规则 3. 当计时器结束时,显示 RAM 中的通知(根据规则 1,这是刚刚过去的那个)。并迭代数据库以找到下一个过期的数据库。冲洗并重复。 (注意,当第一个被处理时,您需要处理边缘情况,因为不会有任何可比较的,而当通知最后一个时,因为不会有任何通知存储在 RAM 中)

      Tada,抱歉,我没有代码示例。但这就是我无数次解决这个问题的方式。效果很好。

      编辑 1:代码

      'main for testing
          Dim notificationScheduler As NotificationScheduler = NotificationScheduler.getInstance
          notificationScheduler.insertNotification(New MyNotificationEntity("Yay, working", DateTime.Now.AddSeconds(15)))
      
          ' expected that the one below will be displayed since insertNotification will only keep track of the newest one in the queue
          ' As mentioned in your post, you have a DB to persist them long term and as such will only need one in the APP's RAM at a time
          notificationScheduler.insertNotification(New MyNotificationEntity("Yay, working-2", DateTime.Now.AddSeconds(3)))
      
      ' myNotificationEntity, will be replaced by whatever class you are using to package your reminder's in a single class (dont see on in your code sample)
      
      Public Class MyNotificationEntity
        Public data As String
        Public timeToShow As DateTime
      
        ' this is a dumb bucket class, you will not end up using this one but rather whatever class you use to contain your notifications
        ' you will need to add _timeToShow as a variable to your class or change the code in the NotificationScheduler to be compatible with your Notification class
      
        Public Sub New(data As String, timeToShow As DateTime)
          Me.data = data
          Me.timeToShow = timeToShow
        End Sub
      End Class
      
      'NotificationScheduler class
      Public Class NotificationScheduler
        Private Shared _instance As NotificationScheduler
        Private Shared ReadOnly _lock As Object = New Object()
      
      
        Dim queuedNotification As MyNotificationEntity
      
        Dim WithEvents timer As System.Windows.Forms.Timer = New Timer
        Dim timerElapsedTime As DateTime = DateTime.Now
      
        Private Sub New()
          timer.Enabled = False
        End Sub
      
        Public Shared Function getInstance()
          ' enforce singleton design pattern (i.e. there should only be one of these in existence)
          ' If this does not make sense, that is fine, at some point lookup the 'singleton design pattern'
          ' Also, SyncLock is a VB (.net really) element that means in a multi-threaded application only one of them at any given time is inside the SyncLock block, 
          '     the rest are queued to alleviate race conditions. Again, if this does not make sense, lookup 'race conditions'
          SyncLock _lock
            If (_instance Is Nothing) Then
              _instance = New NotificationScheduler()
            End If
          End SyncLock
      
          Return _instance
        End Function
      
        ' called after you have placed the new notification in your DB, replaces the currently queued notification only if the new one will be shown first
        Public Sub insertNotification(notificationEntity As MyNotificationEntity)
          If timerElapsedTime.Ticks < notificationEntity.timeToShow.Ticks Then
            queuedNotification = notificationEntity
      
            timer.Stop()
            Dim span As TimeSpan = notificationEntity.timeToShow - timerElapsedTime
            timer.Interval = CInt(span.TotalMilliseconds)
            timer.Start()
          End If
        End Sub
      
        Private Sub timer_elapsed() Handles timer.Tick
          ' the notification time has arrived
          showNotification()
          readNextFromDb()
        End Sub
      
        Private Sub readNextFromDb()
          ' read the next (if any) from the  and handle edge cases for when there is not next one in the DB
          'IMPORTANT: if the one you read from the DB has already happened (i.e. the notification dateTime is after now, notify and do this method again)
      
          '' your code here
        End Sub
      
        Private Sub showNotification()
          MsgBox(queuedNotification.data) ' do whatever notification you want
        End Sub
      End Class
      

      您将需要(看起来)创建类 NotificationDAO(数据访问对象)或 NotificationDTO(数据传输对象)或通用 NotificationEntity。该类将为您需要存储的有关通知的项目(即您在“TblReminder”表中的每一列)提供构造函数和公共实例变量,并且一切都应该很容易工作。

      注意,上面的代码不起作用,也不能检查已经过了通知时间的数据库中的通知,请阅读代码中的 cmets 以获取更多信息。

      【讨论】:

      • @Miguel 下面的解决方案更简单,但是您会毫无意义地花时间检查每一分钟是否应该显示通知。这是非常低效的,并且会导致通知“在一分钟内”准确,而不是在准确的时间。
      • 感谢您的回复,我明白您的意思,但由于这是我的第三个项目,我不知道如何编写大多数解决方案,我尝试在很多论坛上查找解决方案,但没有任何结果向上。你的反应很完美,但我不知道如何编写代码来检查内存中存储的提醒,我对如何比较有点想法,但我需要一些代码来帮助我开始。
      • 今晚下班后让我做饭。
      • @Yousaer10 这是一个winforms应用吗? UWP(通用windows平台)?或者是其他东西?只是想确保我发送的代码是即插即用的。
      • 抱歉,我被抓到做其他工作,我正在使用(Windows Forms App .Net Framework)。感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      相关资源
      最近更新 更多