Imports System.ComponentModel Imports System.Timers Imports System.Collections.ObjectModel Imports System.Windows.Threading Partial Class MainWindow Implements INotifyPropertyChanged Private CurrentTime As TimeSpan Private LapTime As TimeSpan Private LapCount As Integer Private tmr As Timer Private ReadOnly OneSecond As TimeSpan = TimeSpan.FromSeconds(1) Public ReadOnly Property Laps As New ObservableCollection(Of Lap) Public Event PropertyChanged As PropertyChangedEventHandler _ Implements INotifyPropertyChanged.PropertyChanged ' Reproduction context: ' Delay DataContext binding until the first lap exists. Private ReadOnly reproductionTimer As New DispatcherTimer With { .Interval = TimeSpan.FromMilliseconds(50) } Public Sub New() InitializeComponent() AddHandler reproductionTimer.Tick, AddressOf DetectFirstLap reproductionTimer.Start() End Sub Private Sub DetectFirstLap( sender As Object, e As EventArgs ) If Laps.Count = 0 Then Return End If reproductionTimer.Stop() ' Simulates the missing application context: ' binding is established after the first item exists. DataContext = Me End Sub Private Sub StartTimer( sender As Object, e As RoutedEventArgs ) Handles btnStart.Click CurrentTime = TimeSpan.Zero LapTime = TimeSpan.Zero LapCount = 0 tmr = New Timer(1000) With { .Enabled = True } AddHandler tmr.Elapsed, AddressOf UpdateClock End Sub Private Sub UpdateClock( source As Object, e As ElapsedEventArgs ) Dispatcher.Invoke(Sub() PopulateTimer()) End Sub Private Sub PopulateTimer() CurrentTime = CurrentTime.Add(OneSecond) txtDuration.Text = CurrentTime.ToString() End Sub Private Sub CreateLap( sender As Object, e As RoutedEventArgs ) Handles btnLap.Click SaveLap() End Sub Private Sub SaveLap() LapTime = CurrentTime - LapTime LapCount += 1 Laps.Add( New Lap With { .Count = LapCount, .Duration = LapTime }) LapTime = CurrentTime End Sub End Class Public Class Lap Public Property Count As Integer Public Property Duration As TimeSpan End Class