0

I am trying to program a disco light machine in VB.Net. I have four ellipses on a WPF, and I want them to "light up" (=change the fill from white to some color), then wait for 0.5s, then change the fill back to white - all according to a pre-written sequence.

I am trying to use DispatherTimer but I don't actually know how to make it work. The ellipses are name pad0, pad1, etc...

Public Sub timer()
    Dim t As New System.Windows.Threading.DispatcherTimer()
    AddHandler t.Tick, AddressOf dispatcherTimer_Tick
    t.Interval = New TimeSpan(0, 0, 1)
End Sub

Private Sub dispatcherTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
End Sub

Private Sub play_Click(sender As Object, e As RoutedEventArgs) Handles play.Click
    Dim sequence = New Integer() {1, 0, 3, 2}
    For i As Integer = 0 To 3
        Select Case sequence(i)
            Case 0
                pad0.Fill = Brushes.Blue
                **this is where I want the timer to run!**
                padOff(pad0)
            Case 1
                pad1.Fill = Brushes.Yellow
                **this is where I want the timer to run!**
                padOff(pad1)
            Case 2
                pad2.Fill = Brushes.Green
                **this is where I want the timer to run!**
                padOff(pad2)
            Case 3
                pad3.Fill = Brushes.Red
                **this is where I want the timer to run!**
                padOff(pad3)
        End Select
    Next
End Sub

Public Sub padOff(ByVal pad As Shape)
    pad.Fill = Brushes.White
End Sub
David -
  • 2,009
  • 1
  • 13
  • 9
OzW
  • 848
  • 1
  • 11
  • 24

1 Answers1

4

The UI only updates after all your code has executed. Thus, you don't see the change to Blue. Even worse, your UI completely freezes for 0.5s.

The correct way to do this would be to:

  1. Set the color to Blue
  2. Set a timer to expire in 0.5s and set the color to White.

Other alternatives include:

  • Start a new Thread that waits for 0.5s and then changes the color (be sure to use Dispatcher.Invoke here to change the color in the UI thread) or
  • start a BackgroundWorker that waits for 0.5s and changes the color in RunWorkerCompleted (which is already executed in the UI thread) or,
  • use an asnyc wait (e.g. await Task.Delay(500)), which causes the UI to be updated and responsive during the wait period.
Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • 2
    This is WPF. Please don't use Timer and Control.Invoke. There is `DispatcherTimer` instead. – Clemens Aug 12 '14 at 07:42
  • @Clemens: Point taken, I lowercased "timer". Note that the link behind it already links to a description of `DispatcherTimer`, which is the correct timer for WPF. – Heinzi Aug 12 '14 at 07:43
  • @Clemens: Ah, yes, it's Dispatcher.Invoke in WPF. Thanks, fixed. – Heinzi Aug 12 '14 at 07:46
  • @Heinzi Thanks. I'm trying to use a Timer. I've updated my code, still don't really know how to make it work. Would be glad to get more help. – OzW Aug 12 '14 at 14:11