This approach uses a hidden text box you can add to pages you want to be able to trigger methods on from another backgroudn thread in your application. The special class is created globally in your app and then its value is binded to the hidden text box. You can then change the value and the page using the bound text box will get a TextChanged method call in response. Its a hack, but quite a nice one!
IMPORTANT NOTE – This can cause background processes to stall a bit. We've found on a Raspberry Pi 3 using this approach works fine in terms of updating the UI with something, but our SPI port comms would stop for a bit of time and suspect it may be the await call to the UI thread…
Define the special class somewhere
//**********************************************************************************************************
//**********************************************************************************************************
//********** OUR SPECIAL DATABINDING CLASS TO ALLOW US TO TRIGGER PAGE METHODS FROM OTHER THREADS **********
//**********************************************************************************************************
//**********************************************************************************************************
public class PageUpdateDataBinder : System.ComponentModel.INotifyPropertyChanged
{
// Properties
private string _NotifyValue;
public string NotifyValue
{
get { return _NotifyValue; }
set { this.SetProperty(ref this._NotifyValue, value); }
}
//Property Change Logic
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChaned(propertyName);
return true;
}
private void OnPropertyChaned(string propertyName)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
eventHandler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
In your apps global class
public static PageUpdateDataBinder PageUpdateDataBinder1 = null;
In Your Page .xaml file
<!-- Our databinding so we can be updated from other background processes -->
<!-- N.B. you can't use Visibility="Collapsed" as this stops the TextChanged method from being fired, so you'll need to hide this TextBox behind something... -->
<TextBox x:Name="txtOurBackgroundDataBind" Text="{Binding NotifyValue,Mode=TwoWay}" TextChanged="txtOurBackgroundDataBind_TextChanged" ></TextBox>
In your Page .xaml.cs file
In Page_Loading() or Page_Loaded():
//----- SETUP OUR DATABAIND SO OTHER BACKGROUND PROCESSES CAN UPDATE US -----
ApMain.PageUpdateDataBinder1 = new PageUpdateDataBinder {NotifyValue = ""};
this.DataContext = ApMain.PageUpdateDataBinder1;
Method that will get called when the text box value is changed
//*************************************************************************************
//*************************************************************************************
//********** UPDATE FROM SOME OTHER BACKGROUND PROCESSES USING OUR DATABAIND **********
//*************************************************************************************
//*************************************************************************************
private void txtOurBackgroundDataBind_TextChanged(object sender, TextChangedEventArgs e)
{
if (ApMain.PageUpdateDataBinder1.NotifyValue != "") //We will be called again when we clear the value!
{
//Do something
txtMyTextBox.Text = "UPDATE RECEVIED! " + ApMain.PageUpdateDataBinder1.NotifyValue;
}
ApMain.PageUpdateDataBinder1.NotifyValue = "";
}
In your other thread that wants to update the page
//********************************************************
//********************************************************
//********** UPDATE PAGE WE HAVE A DATABIND TO ***********
//********************************************************
//********************************************************
private async void SendPageDataBindUpdate(string NotifyWithValue)
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
ApMain.PageUpdateDataBinder1.NotifyValue = NotifyWithValue;
});
}