I need some help here. I am writing a little desktop app that monitors my ToDo database and whilst it works great when run once, it kind of freaks out when I run it from a timer. As in all the labels start repeating. Below is the entire code.

   Imports System.IO
    Imports System.Runtime.InteropServices
    Imports System.Data
    Imports System.Data.SqlClient

    Public Class ToDoWatcher
        Dim WatchEnabled As Integer
        Dim drag As Boolean
        Dim mousex As Integer
        Dim mousey As Integer
        Const NL As String = vbCrLf 'simple hack to remember what the code for newline is :P
        Dim ServerName As String = "my server"
        Dim CatName As String = "my database"
        Dim DBUserName As String = "my login"
        Dim Password As String = "my password"
        Dim Now As DateTime = DateTime.Now
        Dim RoWCount As Integer

        Private Sub CloseLbl_Click(sender As Object, e As EventArgs) Handles CloseLbl.Click
            Me.Close()
        End Sub
        Private Sub ToDoWatcher_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
            drag = True
            mousex = Windows.Forms.Cursor.Position.X - Me.Left
            mousey = Windows.Forms.Cursor.Position.Y - Me.Top
        End Sub
        Private Sub ToDoWatcher_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
            If drag Then
                Me.Top = Windows.Forms.Cursor.Position.Y - mousey
                Me.Left = Windows.Forms.Cursor.Position.X - mousex
            End If
        End Sub
        Private Sub ToDoWatcher_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
            drag = False
        End Sub
        Private Sub ToDoWatcher_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ToDos()
            'Timer1.Start()
        End Sub
        Private Sub ToDos()

            Dim X As Integer = 5
            Dim Y As Integer = 20
            Dim LB As Label = Nothing
            Dim LBC As Label = Nothing

            Dim Connection As String = "Data Source=" & ServerName & ";Initial Catalog=" & CatName & ";Persist Security Info=True;User ID=" & DBUserName & ";Password=" & Password
            Using con As New SqlConnection(Connection)

                Dim sqlCmd As New SqlCommand("SELECT * FROM TODO ORDER By TDID DESC", con)
                Dim sqlDa As New SqlDataAdapter(sqlCmd)
                Dim dt As New DataTable()
                Dim i As Integer

                sqlDa.Fill(dt)
                RoWCount = dt.Rows.Count.ToString

                If RoWCount > 0 Then
                    For i = 0 To RoWCount - 1
                        Dim isDone As String = dt.Rows(i)("TDDone").ToString()
                        LB = New Label()
                        Panel1.Controls.Add(LB)
                        LB.Visible = True
                        LB.Location = New System.Drawing.Point(X, Y)
                        LB.Size = New Size(310, 20)

                        If isDone = 1 Then
                            LB.Text = dt.Rows(i)("ToDo").ToString()
                            LB.Font = New Font(FontFamily.GenericSerif, 9, FontStyle.Strikeout)
                            LB.ForeColor = Color.LemonChiffon
                        Else
                            LB.ForeColor = Color.Yellow
                            LB.Text = dt.Rows(i)("ToDo").ToString()
                        End If
                        Y = Y + 18
                    Next
                End If
                con.Close()
                con.Dispose()
                sqlCmd = Nothing
                sqlDa = Nothing
                dt = Nothing
                i = Nothing
                LB = Nothing
            End Using
        End Sub
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            ToDos()
        End Sub
    End Class


I can't figure out how to properly dispose of the current info and have it reload on the timer tick :(

What am I missing and if you could be so kind SHOW me what I am missing instead of using a bunch of words I probably would not understand anyway.

Recommended Answers

All 5 Replies

Hi, here's some code that works

Imports System
Imports System.Timers

Module Module1
    Dim aTimer As New System.Timers.Timer
    Dim strMinutes As String
    Dim strNmbrOfSecs As String
    Dim strMilisecs As String
    Dim intInterval As Integer

    Sub Main()
        intInterval = SetInterval()
        aTimer.AutoReset = True
        aTimer.Interval = intInterval '2 seconds
        AddHandler aTimer.Elapsed, AddressOf tick
        aTimer.Start()
        Console.ReadKey()
    End Sub

    Private Function SetInterval() As Integer
        Dim configAppSettings As System.Configuration.AppSettingsReader = New System.Configuration.AppSettingsReader
        strMinutes = CType(configAppSettings.GetValue("strMinutes", GetType(System.String)), String)
        strNmbrOfSecs = CType(configAppSettings.GetValue("strNmbrOfSecs", GetType(System.String)), String)
        strMilisecs = CType(configAppSettings.GetValue("strMilisecs", GetType(System.String)), String)
        Return CType(strMinutes, Integer) * CType(strNmbrOfSecs, Integer) * CType(strMilisecs, Integer)
    End Function


    Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
        Console.WriteLine("tick as {0}", e.SignalTime)
    End Sub

End Module

The trick is creating a handler that reacts on the tick event of the timer

AddHandler aTimer.Elapsed, AddressOf tick

And then do the work in the handler

     Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
        Console.WriteLine("tick as {0}", e.SignalTime)
    End Sub

Thanks for taking the time to answer but...

Either I am not understanding [I am not] or I am not sure you understood my question. The question is that my above code works fine unless it runs via a timer and if it runs via a timer it keeps loading new labels over and over instead of just updating the current labels. So I have on 1st run like 40 labels on 2nd tick I have like 80 labels, and 3rd tick 120 labels. etc.. THAT is what I am having the problems with. I didn't want to send it off as a separate thread as that always causes me greif :(

I have no problems using timers EXCEPT when I am using dymanically created controls. I've tried destroying the control 1st but then it either errors out or doesn't show anything.

I've written many counters with timers so that is not what I need.

But thank you for taking the time to try.

Instead of creating dynamic controls I think you should display the data in a DataGridView or some such control and just update it (if changed) on the timer tick. It would help if you

  1. commented your code to explain what you are trying to do
  2. removed code from the post that is not pertinent to the problem

Try adding the line Panel1.Controls.Clear after line 58 in your posted code. this will remove the previously added labels.

Gary Slutsky THAT is exactly what I was looking for. Thank you so much. One little line of code made all the difference in the world!!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.