Reputation: 434
I'm using Prism Unity for an App for stock management with a bluetooth scanner. At first I used the scanner in HID mode, but the HID initialisation was painfully slow after the scanner was in sleep mode. So I decided to use Bluetooth SPP, which works a lot better. But I'm running in this error and I can't figure out why it's not working.
The Bluetooth service runs in the background and fires an event my ViewModel is subscibed to. Then a function gets called which verifies the barcode and if successful, navigates to another page.
When you enter the barcode manually, the same function gets called to verify and navigate. The interesting code parts below:
The ViewModel Constructor with subscription to the barcode event:
public ArtikelScannenPageViewModel(INavigationService navigationService, IPageDialogService pageDialog, IEventAggregator eventAggregator)
: base(navigationService)
{
Title = "Artikel scannen";
_navigationService = navigationService;
_pageDialog = pageDialog;
_eventAggregator = eventAggregator;
SubmitCommand = new DelegateCommand(OnSubmit);
System.Diagnostics.Debug.WriteLine("BTDevice:" + (string)App.Current.Properties["BTDevice"]);
_eventAggregator.GetEvent<ScannerEvent>().Subscribe(OnBarcode);
}
This gets called when a barcode gets scanned:
private IEventAggregator _eventAggregator;
void OnBarcode(string param)
{
checkArtikel(param);
}
This gets called when a barcode is entered manually:
public DelegateCommand SubmitCommand { protected set; get; }
public async void OnSubmit()
{
if (!string.IsNullOrEmpty(Artikelnr))
{
checkArtikel(Artikelnr);
}
else
{
await _pageDialog.DisplayAlertAsync("Eingabe", "Bitte Artikelnummer eingeben!", "OK");
}
}
Both, OnSubmit and OnBarcode, use this function:
public async void checkArtikel(string _barcode)
{
DataOperations dop = new DataOperations();
APIOperations.ValidationResponse vr = await dop.GetArtikel(_barcode);
if (vr.Successful)
{
Artikel artikel = (Artikel)vr.Response;
NavigationParameters p = new NavigationParameters();
p.Add("artikel", artikel);
await _navigationService.NavigateAsync(_nextPage, p);
System.Diagnostics.Debug.WriteLine("Navigation fired!");
}
else
{
await _pageDialog.DisplayAlertAsync("Fehler", "Falsche Artikel-Nr. oder Artikel tot!", "OK");
}
}
When it's entered manually, everything works fine. But when OnBarcode is called, the Navigation does not work! It just stays on the page. The checkArtikel function gets called. The DataOperation returns the right "Artikel" and even the "Navigation fired!" appears in the log. How could that be possible? I'm litteraly using the same function? What am I missing here?
Edit: typo
Upvotes: 0
Views: 207
Reputation: 434
Seems like the navigation and pagedialog was not called from main thread when called over OnBarcode. I fixed it by putting the navigation and pagedialog inside Device.BeginInvokeOnMainThread(). It now looks like this:
public async void CheckArtikel(string _barcode)
{
DataOperations dop = new DataOperations();
APIOperations.ValidationResponse vr = await dop.GetArtikel(_barcode);
if (vr.Successful)
{
Artikel artikel = (Artikel)vr.Response;
NavigationParameters p = new NavigationParameters
{
{ "artikel", artikel }
};
Device.BeginInvokeOnMainThread(async() => await _navigationService.NavigateAsync(_nextPage, p));
}
else
{
Device.BeginInvokeOnMainThread(async () => await _pageDialog.DisplayAlertAsync("Fehler", "Falsche Artikel-Nr. oder Artikel tot!", "OK"));
}
}
Upvotes: 1