Das App-Template nutzt die sogenannte „Dependency Injection„, um zum Beispiel den aktuellen Dispatcher in das ViewModel zu injizieren. Somit steht immer der richtige Dispatcher zur Verfügung und Code, welcher auf dem UIThread ausgeführt werden muss, kann einfach über unseren DispatchManager ausgeführt werden.
Constructor (ctor)
Damit eine View bzw. ein ViewModel auch den Dispatcher empfangen kann, muss der Ctor wie folgt angepasst werden (sofern Ihr eine neue View bzw. ein neues ViewModel anlegt).
ViewModel
Das neue ViewModel sollte immer vom AppViewModel erben. Damit erhält es Zugriff auf alle gemeinsam genutzten Funktionen und Methoden. Der Ctor muss als Parameter einen IDispatcher annehmen, und diesen auch an die Basis-Klasse weitergeben.
public partial class DashboardPageViewModel : AppViewModel { #region Ctor public DashboardPageViewModel(IDispatcher dispatcher) : base(dispatcher) { Dispatcher = dispatcher; } #endregion // Some code... }
Views
In der View muss der Ctor dann das gewünschte ViewModel als Parameter übergeben werden.
public partial class DashboardPage : ContentPage { public DashboardPage(DashboardPageViewModel viewModel) { InitializeComponent(); BindingContext = viewModel; } }
DispatchManager
Der DispatchManager ist eine Helper-Klasse, welche es Ihnen einfach ermöglicht Code über den Dispatcher auszuführen. Durch das vorgeschaltete trycatch werden auch direkt Fehler abgefangen und protokoliert (EventManger).
Einfaches Beispiel
Hier wird die Eigenschaft „IsRefreshing“ Thread-Safe auf „false“ gesetzt.
DispatchManager.Dispatch(Dispatcher, () => IsRefreshing = false);
Da es sich bei dieser Eigenschaft um ein Element handelt, welches ein Binding auf ein UI-Element hat, muss dieses zwangsweise am MainThread der Applikation ausgeführt werden. Andernfalls kann es hier zu einer Ausnahme bzw. einen Crash kommen.
CodeSnippet dispatchen
Um einen ganzen Codeblock zu dispatchen, kann die Funktion wie folgt aussehen.
DispatchManager.Dispatch(Dispatcher, () => { CurrentJobInfo = DemoManager.JobInfo; PrintersState = DemoManager.PrinterState.Printer; ServerSettings = DemoManager.ServerSettings; Files = DemoManager.Files; });
Dispatching abwarten
Manchmal kann es nötig sein, dass Dispatching abzuwarten (await). Dazu muss die DispatchAsync() Methode verwendet werden.
await DispatchManager.DispatchAsync(Dispatcher, UpdateFromInstanceData); // Or await DispatchManager.DispatchAsync(Dispatcher, () => { IsRefreshing = true; IsReachable = false; SelectedServer = Servers.FirstOrDefault(server => server.Id == LastServerId); SelectedServerAddress = SelectedServer?.FullWebAddress; }); await CheckOnlineStateSelectedServer();