What is a BondFiled column? Do you mean a bound field column? What kind of data does it contain and what do you want to happen? How will the timer be started and stopped? Do you want one countdown for each record? Details please.

Edited 3 Years Ago by Reverend Jim

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        DataGridView1.Rows.Add({"Jim", 12})
        DataGridView1.Rows.Add({"Bob", 19})

    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        Timer1.Enabled = True

    End Sub

    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick

        For row As Integer = 0 To DataGridView1.Rows.Count - 1
            Dim num As Integer = DataGridView1.Rows(row).Cells(1).Value
            DataGridView1.Rows(row).Cells(1).Value = num - 1
        Next

    End Sub

End Class

This is a simple case. You can modify it to handle the date/time as you display it.

It's cold and raining and I don't feel like doing the dishes, and this looked like an interesting diversion, so here you go with a dgv Column to countdown from a datetime column. :) Boy how I wish this forum supported putting code in a scrollbox!

Public Class Form1

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Dim dt As New DataTable
      Dim r As DataRow
      With dt
         .Columns.Add("dt", GetType(DateTime))
         r = .NewRow : r(0) = Now.AddMinutes(1) : .Rows.Add(r)
         r = .NewRow : r(0) = Now.AddHours(1) : .Rows.Add(r)
         r = .NewRow : r(0) = Now.AddSeconds(10) : .Rows.Add(r)
         r = .NewRow : r(0) = Now.AddDays(1).AddHours(2).AddMinutes(5) : .Rows.Add(r)
      End With
      DataGridView1.DataSource = dt
      Dim countdown As New DGVColumnDateCountDown
      countdown.ComparisionColumn = DataGridView1.Columns("dt")

      DataGridView1.Columns.Add(countdown)

   End Sub

End Class

Public Class DGVColumnDateCountDown
   Inherits DataGridViewTextBoxColumn
   Public Sub New()
      [ReadOnly] = True
      tmrUpdate.Start()
   End Sub

   Private WithEvents tmrUpdate As New System.Windows.Forms.Timer With {.Interval = 1000}

   Private _PositiveColor As Color = Color.Black
   Public Property PositiveColor() As Color
      Get
         Return _PositiveColor
      End Get
      Set(ByVal value As Color)
         _PositiveColor = value
      End Set
   End Property 'PositiveColor


   Private _NegativeColor As Color = Color.Red
   Public Property NegativeColor() As Color
      Get
         Return _NegativeColor
      End Get
      Set(ByVal value As Color)
         _NegativeColor = value
      End Set
   End Property 'NegativeColor


   Private _ComparisionColumn As DataGridViewColumn
   Public Property ComparisionColumn() As DataGridViewColumn
      Get
         Return _ComparisionColumn
      End Get
      Set(ByVal value As DataGridViewColumn)
         _ComparisionColumn = value
      End Set
   End Property 'SourceColumn

   Private _UpdateInterval As Int32
   <System.ComponentModel.Description("Update time in seconds")> _
   Public Property UpdateInterval() As Int32
      Get
         Return _UpdateInterval
      End Get
      Set(ByVal value As Int32)
         If value < 0 Then Throw New ArgumentException("Must be >= 0")
         _UpdateInterval = value * 1000
      End Set
   End Property 'UpdateInterval

   Private Sub SetTimer()
      If _UpdateInterval = 0 Then
         tmrUpdate.Enabled = False
      Else
         tmrUpdate.Interval = _UpdateInterval
         tmrUpdate.Enabled = True
      End If
   End Sub

   Private Sub tmrUpdate_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmrUpdate.Tick
      If Me.DataGridView Is Nothing OrElse ComparisionColumn.DataGridView Is Nothing Then Exit Sub
      If Not ComparisionColumn.DataGridView.Equals(Me.DataGridView) Then
         Throw New ArgumentException("Invalid Source Column on Countdown Column: " & Me.Name)
      End If
      Dim si As Int32 = ComparisionColumn.Index
      Dim dtsource As DateTime

      Dim currentTime As DateTime = Now 'lock time for update

      For Each row As DataGridViewRow In Me.DataGridView.Rows

         If row.Cells(si).Value IsNot Nothing Then
            ' see if it is a valid date
            If row.Cells(si).ValueType Is GetType(DateTime) Then
               dtsource = CType(row.Cells(si).Value, DateTime)
               If dtsource <> DateTime.MinValue Then
                  ' got something to work with
                  Dim diff As dtDifferenceStruct = dtDifference(dtsource, currentTime)
                  Dim sb As New System.Text.StringBuilder(50)
                  sb.Append(diff.Years.ToString & " years ")
                  sb.Append(diff.Months.ToString & " months ")
                  sb.Append(diff.Days.ToString & " days ")
                  sb.Append(diff.Hrs.ToString & " hours ")
                  sb.Append(diff.Sec.ToString & " seconds")
                  If diff.Preceeding Then
                     row.Cells(Index).Style.ForeColor = NegativeColor
                  Else
                     row.Cells(Index).Style.ForeColor = PositiveColor
                  End If
                  row.Cells(Index).Value = sb.ToString
               Else
                  row.Cells(Index).Value = ""
               End If

            End If
         End If
      Next

   End Sub

   Private Structure dtDifferenceStruct
      Public Years As Int32
      Public Months As Int32
      Public Days As Int32
      Public Hrs As Int32
      Public Min As Int32
      Public Sec As Int32
      Public MillSec As Int32
      Public Preceeding As Boolean
   End Structure

   Private Function dtDifference(ByVal LatterDate As DateTime, ByVal EarlierDate As DateTime) As dtDifferenceStruct
      Dim ret As New dtDifferenceStruct

      ' accumulator should start with the smaller of the 2 datetimes
      Dim accumulator As DateTime

      If LatterDate >= EarlierDate Then
         ret.Preceeding = False
         accumulator = EarlierDate
      Else
         ret.Preceeding = True
         accumulator = LatterDate
         LatterDate = EarlierDate
      End If

      Dim ts As TimeSpan = LatterDate.Subtract(accumulator)
      ret.Years = CInt(Microsoft.VisualBasic.DateDiff(DateInterval.Year, accumulator, LatterDate))
      accumulator = accumulator.AddYears(ret.Years)

      ts = LatterDate.Subtract(accumulator)
      ret.Months = CInt(Microsoft.VisualBasic.DateDiff(DateInterval.Month, accumulator, LatterDate))
      accumulator = accumulator.AddMonths(ret.Months)

      ts = LatterDate.Subtract(accumulator)
      ret.Days = CInt(Microsoft.VisualBasic.DateDiff(DateInterval.Day, accumulator, LatterDate))
      accumulator = accumulator.AddDays(ret.Days)

      ts = LatterDate.Subtract(accumulator)
      ret.Hrs = CInt(Microsoft.VisualBasic.DateDiff(DateInterval.Hour, accumulator, LatterDate))
      accumulator = accumulator.AddHours(ret.Hrs)

      ts = LatterDate.Subtract(accumulator)
      ret.Min = CInt(Microsoft.VisualBasic.DateDiff(DateInterval.Minute, accumulator, LatterDate))
      accumulator = accumulator.AddMinutes(ret.Min)

      ts = LatterDate.Subtract(accumulator)
      ret.Sec = CInt(Microsoft.VisualBasic.DateDiff(DateInterval.Second, accumulator, LatterDate))
      accumulator = accumulator.AddSeconds(ret.Sec)

      ts = LatterDate.Subtract(accumulator)
      ret.MillSec = ts.Milliseconds

      Return ret
   End Function
End Class
This article has been dead for over six months. Start a new discussion instead.