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.
LVL 9
samiam41Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jimyXCommented:
I do not use VB, but I can participate as long as this Q is Neglected and Mics. Programming is involved.

You need to use Timer that calculates, every 30 sec or so, the time difference from now and all the listed appointments.
0
ste5anSenior DeveloperCommented:
jimy is right. Use a timer. The timer resolution should be 1 second.

But the problem is: How is waiting defined?
0
samiam41Author Commented:
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.
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

it_saigeDeveloperCommented:
Here's one way you could do it:

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

Open in new window


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

Open in new window

Produces the following output -Each data object is responsible for updating the wait time.  An event is used to call out from the data object that it's wait time has updated.Once the wait time reaches the 5 minute threshold, a notification is sent.-saige-
0
samiam41Author Commented:
Sam's DatagridviewThanks 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.
0
it_saigeDeveloperCommented:
The wait time does not have to display on the form.  My example was just showing how events would be used to call out from the timer method.

I used two events.  The first event is just a tick so that every second the wait time on the form is updated.  The second event fires when the calculated threshold is breached.  The threshold is calculated by: Waiting.Minutes Mod 5 = 0.  In order to stop the timer, you would set the IsAssisted property to true (would probably be better as a method so that it could not be set to false again unless that is the type of functionality you are after.

Another note, is that each data layer object implements it's own timer and fires the appropriate events.

-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
samiam41Author Commented:
Thanks saige this has been a tremendous help.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.