samiam41
asked on
Automatically send notifications when time = 5 minutes in vb.net 2010
I developed a client notification program for my company and I am needing a way to send popup notifications to a person once the client has been waiting for specific periods of time. I need to send a popup to the supervisor of a particular department when the time has exceeded 5, 10, and 15 minutes.
I am using a Datagridview in vb.net 2010 to store the appointment information. Once a field in the Datagridview exceed that timeframe is when I need the popup sent.
Any help would be greatly appreciated.
I am using a Datagridview in vb.net 2010 to store the appointment information. Once a field in the Datagridview exceed that timeframe is when I need the popup sent.
Any help would be greatly appreciated.
jimy is right. Use a timer. The timer resolution should be 1 second.
But the problem is: How is waiting defined?
But the problem is: How is waiting defined?
ASKER
That is the part I can't seam to get, how is waiting defined. It would have to check each record in datagridview which would have different start times. How could I set a timer to check each individual record to see if the wait time is at a certain interval.
Here's one way you could do it:
Form1.vb -
Form1.Designer.vb -
Form1.vb -
Imports System.ComponentModel
Imports System.Text
Public Class Form1
Private ReadOnly customers As New BindingList(Of Customer)()
Private ReadOnly names As New List(Of String)() From {"Sally", "Paul", "Susan", "Peter", "Julia", "Jimmy", "Mary", "Michael", "Alexis", "Darren"}
Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
For i As Integer = 0 To names.Count - 1
AddCustomer(i, names(i), DateTime.Now().AddSeconds(-i * 30))
Next
BindingSource1.DataSource = customers
DataGridView1.DataSource = BindingSource1
End Sub
Private Sub AddCustomer(ByVal id As Integer, ByVal name As String, ByVal arrived As DateTime)
Dim customer As New Customer(New List(Of String) From {"Jack", "Jill"}) With {.ID = id, .Name = name, .Arrived = arrived}
customers.Add(customer)
AddHandler customer.WaitingTick, AddressOf OnWaitingTick
AddHandler customer.SendNotification, AddressOf OnSendNotification
End Sub
Private Sub OnWaitingTick(ByVal sender As Object, ByVal e As EventArgs)
BindingSource1.ResetBindings(False)
End Sub
Private Sub OnSendNotification(ByVal sender As Object, ByVal e As NotificationEventArgs)
Dim sb As New StringBuilder()
For i As Integer = 0 To e.Recipients.Count - 1
If i = 0 Then
sb.Append(e.Recipients(i))
ElseIf i = e.Recipients.Count - 1 Then
sb.Append(String.Format(" and {0}", e.Recipients(i)))
Else
sb.Append(String.Format(", {0}", e.Recipients(i)))
End If
Next
MessageBox.Show(String.Format("Notification for {0} would be sent to {1}", DirectCast(sender, Customer).Name, sb))
End Sub
Private Sub OnCellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
If e.Value IsNot Nothing Then
Try
If DataGridView1.Columns(e.ColumnIndex).Name().Equals(ColumnArrived.Name()) Then
Dim [date] As DateTime
If DateTime.TryParse(e.Value.ToString(), [date]) Then
e.Value = [date].ToString("hh:mm:ss tt")
e.FormattingApplied = True
End If
ElseIf DataGridView1.Columns(e.ColumnIndex).Name.Equals(ColumnWaiting.Name()) Then
Dim [span] As TimeSpan
If TimeSpan.TryParse(e.Value.ToString(), [span]) Then
e.Value = String.Format("{0}:{1}:{2}", [span].Hours.ToString("00"), [span].Minutes.ToString("00"), [span].Seconds.ToString("00"))
e.FormattingApplied = True
End If
End If
Catch ex As Exception
e.FormattingApplied = False
End Try
End If
End Sub
End Class
Class Customer
#Region "Waiting Period Event Handlers"
Private ReadOnly fWaitingTickEventHandlers As New List(Of WaitingTickEventHandler)
Public Custom Event WaitingTick As WaitingTickEventHandler
AddHandler(ByVal value As WaitingTickEventHandler)
fWaitingTickEventHandlers.Add(value)
End AddHandler
RemoveHandler(ByVal value As WaitingTickEventHandler)
fWaitingTickEventHandlers.Remove(value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
For Each handler As WaitingTickEventHandler In fWaitingTickEventHandlers
Try
handler.Invoke(sender, e)
Catch ex As Exception
Debug.WriteLine(String.Format("Exception reported while invoking event handler: {0}", ex))
End Try
Next
End RaiseEvent
End Event
Protected Overridable Sub OnWaitingTick(ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent WaitingTick(sender, e)
End Sub
#End Region
#Region "Notification Event Handlers"
Private ReadOnly fNotificationEventHandlers As New List(Of NotificationEventHandler)
Public Custom Event SendNotification As NotificationEventHandler
AddHandler(ByVal value As NotificationEventHandler)
fNotificationEventHandlers.Add(value)
End AddHandler
RemoveHandler(ByVal value As NotificationEventHandler)
fNotificationEventHandlers.Remove(value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As NotificationEventArgs)
For Each handler As NotificationEventHandler In fNotificationEventHandlers
Try
handler.Invoke(sender, e)
Catch ex As Exception
Debug.WriteLine(String.Format("Exception reported while invoking event handler: {0}", ex))
End Try
Next
End RaiseEvent
End Event
Protected Overridable Sub OnSendNotification(ByVal sender As Object, ByVal e As NotificationEventArgs)
RaiseEvent SendNotification(sender, e)
End Sub
#End Region
Private fID As Integer
Private fName As String
Private ReadOnly fRecipients As IEnumerable(Of String)
Private fArrived As DateTime
Private fIsAssisted As Boolean = False
Private WithEvents fArrivedTimer As System.Windows.Forms.Timer
Private fCanNotify As Boolean = False
Public Property ID() As Integer
Get
Return fID
End Get
Set(ByVal value As Integer)
If Not value.Equals(fID) Then
fID = value
End If
End Set
End Property
Public Property Name() As String
Get
Return fName
End Get
Set(ByVal value As String)
If Not value.Equals(fName) Then
fName = value
End If
End Set
End Property
Public Property Arrived() As DateTime
Get
Return fArrived
End Get
Set(ByVal value As DateTime)
If Not value.Equals(fArrived) Then
fArrived = value
If fArrivedTimer Is Nothing Then fArrivedTimer = New System.Windows.Forms.Timer() With {.Interval = New TimeSpan(0, 0, 1).Milliseconds}
fArrivedTimer.Start()
End If
End Set
End Property
Public ReadOnly Property Waiting() As TimeSpan
Get
Return DateTime.Now - fArrived
End Get
End Property
Public Property IsAssisted() As Boolean
Get
Return fIsAssisted
End Get
Set(ByVal value As Boolean)
If Not value.Equals(fIsAssisted) Then
fIsAssisted = value
End If
End Set
End Property
Public Sub New(Optional ByVal Recipients As IEnumerable(Of String) = Nothing)
fArrivedTimer = New System.Windows.Forms.Timer() With {.Interval = New TimeSpan(0, 0, 1).TotalMilliseconds()}
If Recipients Is Nothing Then Recipients = New List(Of String)
fRecipients = Recipients
End Sub
Public Sub OnTick(ByVal sender As Object, ByVal e As EventArgs) Handles fArrivedTimer.Tick
If Not fIsAssisted Then
OnWaitingTick(Me, EventArgs.Empty)
Dim remainder = Waiting.Minutes Mod 5
Console.WriteLine("{0} has a waiting time of {1} with a remainder of {2}", Name, Waiting, remainder)
If Waiting.Minutes > 0 AndAlso Waiting.Minutes Mod 5 = 0 AndAlso fCanNotify Then
fCanNotify = False
OnSendNotification(Me, New NotificationEventArgs(fRecipients))
Else
If Waiting.Minutes <> 0 AndAlso Waiting.Minutes Mod 5 >= 1 Then fCanNotify = True
End If
Else
fArrivedTimer.Stop()
End If
End Sub
End Class
Public Delegate Sub WaitingTickEventHandler(ByVal sender As Object, ByVal e As EventArgs)
Public Delegate Sub NotificationEventHandler(ByVal sender As Object, ByVal e As NotificationEventArgs)
Public Class NotificationEventArgs
Inherits EventArgs
Private ReadOnly fRecipients As IEnumerable(Of String)
Public ReadOnly Property Recipients() As IEnumerable(Of String)
Get
Return fRecipients
End Get
End Property
Private Sub New()
End Sub
Public Sub New(ByVal Recipients As IEnumerable(Of String))
fRecipients = Recipients
End Sub
End Class
Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.DataGridView1 = New System.Windows.Forms.DataGridView()
Me.ColumnID = New System.Windows.Forms.DataGridViewTextBoxColumn()
Me.ColumnName = New System.Windows.Forms.DataGridViewTextBoxColumn()
Me.ColumnArrived = New System.Windows.Forms.DataGridViewTextBoxColumn()
Me.ColumnWaiting = New System.Windows.Forms.DataGridViewTextBoxColumn()
Me.ColumnHelp = New System.Windows.Forms.DataGridViewButtonColumn()
Me.BindingSource1 = New System.Windows.Forms.BindingSource(Me.components)
CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.BindingSource1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'DataGridView1
'
Me.DataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.DataGridView1.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() {Me.ColumnID, Me.ColumnName, Me.ColumnArrived, Me.ColumnWaiting, Me.ColumnHelp})
Me.DataGridView1.Location = New System.Drawing.Point(13, 13)
Me.DataGridView1.Name = "DataGridView1"
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.Size = New System.Drawing.Size(634, 341)
Me.DataGridView1.TabIndex = 0
'
'ColumnID
'
Me.ColumnID.DataPropertyName = "ID"
Me.ColumnID.HeaderText = "ID"
Me.ColumnID.Name = "ColumnID"
Me.ColumnID.ReadOnly = True
Me.ColumnID.Visible = False
'
'ColumnName
'
Me.ColumnName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill
Me.ColumnName.DataPropertyName = "Name"
Me.ColumnName.HeaderText = "Name"
Me.ColumnName.Name = "ColumnName"
Me.ColumnName.ReadOnly = True
'
'ColumnArrived
'
Me.ColumnArrived.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells
Me.ColumnArrived.DataPropertyName = "Arrived"
Me.ColumnArrived.HeaderText = "Time Arrived"
Me.ColumnArrived.Name = "ColumnArrived"
Me.ColumnArrived.ReadOnly = True
Me.ColumnArrived.Width = 84
'
'ColumnWaiting
'
Me.ColumnWaiting.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells
Me.ColumnWaiting.DataPropertyName = "Waiting"
Me.ColumnWaiting.HeaderText = "Time Waiting"
Me.ColumnWaiting.Name = "ColumnWaiting"
Me.ColumnWaiting.ReadOnly = True
Me.ColumnWaiting.Width = 87
'
'ColumnHelp
'
Me.ColumnHelp.HeaderText = "Assistance Provided"
Me.ColumnHelp.Name = "ColumnHelp"
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(659, 366)
Me.Controls.Add(Me.DataGridView1)
Me.Name = "Form1"
Me.Text = "Form1"
CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.BindingSource1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Friend WithEvents DataGridView1 As System.Windows.Forms.DataGridView
Friend WithEvents ColumnID As System.Windows.Forms.DataGridViewTextBoxColumn
Friend WithEvents ColumnName As System.Windows.Forms.DataGridViewTextBoxColumn
Friend WithEvents ColumnArrived As System.Windows.Forms.DataGridViewTextBoxColumn
Friend WithEvents ColumnWaiting As System.Windows.Forms.DataGridViewTextBoxColumn
Friend WithEvents ColumnHelp As System.Windows.Forms.DataGridViewButtonColumn
Friend WithEvents BindingSource1 As System.Windows.Forms.BindingSource
End Class
Produces the following output --saige-
ASKER
Thanks saige,
That is a little more then I think I can understand. I have the send notification part down. I don't understand the wait time part. I do not want the wait time for my datagridview to display on the form. It will be running in the background. I guess I should have mentioned that earlier.
Let me explain a little better. When a client comes to our office they get put into the client notification system. The status form is where I have the datagridview that needs to notify a supervisor if that client is waiting too long. The wait time needs to be calculated from the start time or the time they are put into the system. Once they have waited for a specific amount of time the supervisors gets a notification. If they have waited longer then another specific amount of time the sup gets a notification.
I can send the notification that part I've got. I don't know how to set up each line item to determine what the wait times are for each individual line. Attached is a example of my datagridview.
That is a little more then I think I can understand. I have the send notification part down. I don't understand the wait time part. I do not want the wait time for my datagridview to display on the form. It will be running in the background. I guess I should have mentioned that earlier.
Let me explain a little better. When a client comes to our office they get put into the client notification system. The status form is where I have the datagridview that needs to notify a supervisor if that client is waiting too long. The wait time needs to be calculated from the start time or the time they are put into the system. Once they have waited for a specific amount of time the supervisors gets a notification. If they have waited longer then another specific amount of time the sup gets a notification.
I can send the notification that part I've got. I don't know how to set up each line item to determine what the wait times are for each individual line. Attached is a example of my datagridview.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks saige this has been a tremendous help.
You need to use Timer that calculates, every 30 sec or so, the time difference from now and all the listed appointments.