Hi,
I have resolved this issue and thought I would share the method here as it may be useful to others…..
To make the UI elements accessible from both the window creation and update I initialised the UIElements at the class level
using GHIElectronics.TinyCLR.UI;
using GHIElectronics.TinyCLR.UI.Controls;
using GHIElectronics.TinyCLR.UI.Threading;
using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Threading;
namespace FBBAA_Emulator
{
///
/// Partial class that extends the main Program class
/// purely to make the code more managable
///
internal partial class Program : Application
{
public static Text AQValue = new Text();
public static Text ThresholdValue = new Text();
...
Then when I create the window I instantiate the elements along with anything else on screen. In my case I have a panel the full size of the screen and inside that I have two panels, one on the left and one on the right. These panels will hold the UI elements I want (I have only included some here, and for the purposes of simplicity the right panel is empty).
Note that I also add a button on the screen with it’s event handler
private static UIElement Elements(DisplayController display)
{
//First create a panel for the entire screen
var fullPanel = new StackPanel(Orientation.Horizontal);
fullPanel.HorizontalAlignment = HorizontalAlignment.Center;
//Now create a left side inner panel
var leftPanel = new StackPanel(Orientation.Vertical);
leftPanel.Width = display.ActiveConfiguration.Width / 2;
leftPanel.HorizontalAlignment = HorizontalAlignment.Left;
//Now create a right side inner panel
var rightPanel = new StackPanel(Orientation.Vertical);
rightPanel.Width = display.ActiveConfiguration.Width / 2;
rightPanel.HorizontalAlignment = HorizontalAlignment.Right;
//Now build the elements in the left panel
AQValue = new Text()
{
Font = font10pnt,
TextContent = "AQ: 100%",
ForeColor = Colors.Gray,
Height = 20,
Width = 240,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
};
ThresholdValue = new Text
{
Font = font10pnt,
TextContent = “Threshold: 75%”,
ForeColor = Colors.Gray,
Height = 20,
Width = leftPanel.Width,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
};
var txtSettings = new Text(font10pnt, “Change Settings”)
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
};
//Add a button to allow settings change
var Settingsbutton = new Button()
{
Child = txtSettings,
Width = 100,
Height = 40
};
Settingsbutton.Click += Settingsbutton_Click;
//And assemble the left panel fields
leftPanel.Children.Add(AQValue);
leftPanel.Children.Add(ThresholdValue);
leftPanel.Children.Add(Settingsbutton);
fullPanel.Children.Add(leftPanel);
fullPanel.Children.Add(rightPanel);
return fullPanel;
}
Button click handler:
private static void Settingsbutton_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine(“click”);
//Test code to set the AQ back to 100%
app.UpdateAQ(100);
}
In Addition I have a hardware button setup by:
var BtnApp = GpioController.GetDefault().OpenPin(SC20260.GpioPin.PB7);
BtnApp.SetDriveMode(GpioPinDriveMode.InputPullUp);
BtnApp.ValueChanged += BtnApp_ValueChanged;
and the button event handler which increments AQ by one for each press:
private static void BtnApp_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
{
if (e.Edge == GpioPinEdge.FallingEdge)
{
Debug.WriteLine("App button pressed");
app.UpdateAQ(app.aq);
app.aq++;
if (app.aq > 100)
{
app.aq = 50;
}
app.UpdateThresold(30);
}
}
Now we get to the main part; how to change the value of a UIElement on screen during execution. I created a method called UpdateAQ() which sets a new value for the UIElement
public void UpdateAQ(int NewValue)
{
Text txt = (Text)Program.AQValue;
Application.Current.Dispatcher.Invoke(TimeSpan.FromMilliseconds(10), _ =>
{
txt.TextContent = "AQ: " + NewValue.ToString() + “%”;
txt.Invalidate();
return null;
}, null);
}
This will change the AQ Text UI element to the value passed in NewValue
I also created a method to change the value of a second UI element (called ThresholdValue)
public void UpdateThresold(int NewValue)
{
Text txt = (Text)Program.ThresholdValue;
if(Application.Current.Dispatcher.CheckAccess())
{
Debug.WriteLine("Thread not ready");
}
else
{
Application.Current.Dispatcher.Invoke(TimeSpan.FromMilliseconds(100), _ =>
{
try
{
txt.TextContent = "Threshold: " + NewValue.ToString() + "%";
txt.Invalidate();
}
catch (Exception ex)
{
Debug.WriteLine("Invoke cuased exception " + ex.Message);
}
return null;
}, null);
}
}
Note that in this second method I check access to the UI thread before updating the value and also put try/catch around the update, actually these are not necessary but might be considered good practice.
So far, this seems to work well