To open the graphics editor, we double-clicked on
MainPage.xaml in the Solution Explorer. If you single-click on it instead,
MainPage.xaml.cs will be shown below. Double-click on
MainPage.xaml.cs The file will open in a new edit window, and this will be our main program file:
Headed applications support threading, just like headless applications. But, there’s a detail to be aware of: user interface operations must always occur on the user-interface thread. The
MainPage function is originally called on the UI thread, so we need to arrange things such that our UI updates always happen on this same thread.
Although we don’t need to update the real LED on the UI thread, we do need to update the virtual LED on the screen from the main thread.
In BlinkyHeadless, we started a new thread for the timer. In BlinkyHeaded, we will use a
DispatcherTimer instead. This timer is guaranteed to execute on the main UI thread. It is said to be “synchronous”. Meaning that our
Timer-Tick routine will be called when the UI thread isn’t doing anything else. The BlinkyHeadless timer was “asynchronous”, that is, it could happen at any time, regardless of what the main thread is doing.
Let’s add the timer to the function
Note the error line underneath
Timer_Tick. That’s because we haven’t declared the
Timer_Tick function yet. Let’s do that next.
Timer_Tick is going to look just about the same as
Timer_Tick from BlinkyHeadless. But we’re going to add the code to “blink” the LED on screen. We do that by filling the ellipse with either red or gray color.
Our colors will be controlled by the Brush object. We’ll need a
gray_brush object and a
red_brush object. These will be declared as global objects, and we’ll put them right after the
DispatcherTimer global object:
Recall that we named the ellipse
LED. Filling the ellipse object is straightforward; we just call the
Fill method of the LED object. Here’s our
Of course, we have some errors because we haven’t declared our
Gpio objects yet. We’ll need a
InitGPIO function, just like we had in BlinkyHeadless. We’ll also need the same set of
Gpio variables we had in BlinkyHeadless:
We’ll just copy the
InitGPIO function over from BlinkyHeadless, and add some messages to take advantage of the
GpioStatus text block we included in the UI:
We still have some syntax errors, but those will go away when include our using statement for
All that’s left to do is call
InitGPIO from the
MainPage function, start the timer, and the program is done: