Tutte le piattaforme MvvmCross richiedono che UI-azioni vengono schierate nuovamente al UI Discussione/appartamento - ma ogni piattaforma fa questo in modo diverso ....
Per ovviare a questo, MvvmCross fornisce un modo cross-platform per fare ciò - usando un oggetto iniettato IMvxViewDispatcherProvider
.
Per esempio, su WindowsPhone IMvxViewDispatcherProvider
è fornito in ultima analisi, da MvxMainThreadDispatcher
in https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxMainThreadDispatcher.cs
Questo implementa la InvokeOnMainThread
utilizzando:
private bool InvokeOrBeginInvoke(Action action)
{
if (_uiDispatcher.CheckAccess())
action();
else
_uiDispatcher.BeginInvoke(action);
return true;
}
Per il codice in ViewModels:
- tua
ViewModel
eredita da MvxViewModel
- i
MvxViewModel
eredita da un MvxApplicationObject
- i
MvxApplicationObject
eredita da un MvxNotifyPropertyChanged
- l'oggetto
MvxNotifyPropertyChanged
eredita da un MvxMainThreadDispatchingObject
MvxMainThreadDispatchingObject
è https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/ViewModels/MvxMainThreadDispatchingObject.cs
public abstract class MvxMainThreadDispatchingObject
: IMvxServiceConsumer<IMvxViewDispatcherProvider>
{
protected IMvxViewDispatcher ViewDispatcher
{
get { return this.GetService().Dispatcher; }
}
protected void InvokeOnMainThread(Action action)
{
if (ViewDispatcher != null)
ViewDispatcher.RequestMainThreadAction(action);
}
}
Quindi ... il tuo punto di vista Modello può chiamare InvokeOnMainThread(() => DoStuff());
Un altro punto da notare è che MvvmCross fa automaticamente conversioni thread dell'interfaccia utente per gli aggiornamenti di proprietà che vengono segnalati in un MvxViewModel
(né in alcuna MvxNotifyPropertyChanged
oggetto) attraverso i RaisePropertyChanged()
metodi - vedi:
protected void RaisePropertyChanged(string whichProperty)
{
// check for subscription before going multithreaded
if (PropertyChanged == null)
return;
InvokeOnMainThread(
() =>
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(whichProperty));
});
}
in https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/ViewModels/MvxNotifyPropertyChanged.cs
Questo il marshalling automatico delle chiamate RaisePropertyChanged()
funziona bene per la maggior parte delle situazioni, ma può essere un po 'inefficiente se si aumentano molte proprietà modificate da un thread in background, si può verificare un elevato cambio di contesto dei thread. Non è qualcosa che è necessario essere a conoscenza di nella maggior parte del codice - ma se mai lo trovo è un problema, allora può aiutare a cambiare il codice come:
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
a:
InvokeOnMainThread(() => {
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
});
Se mai utilizzate ObservableCollection
, poi si ricorda che MvvmCross fa non effettuare una discussione smistamento per le INotifyPropertyChanged
o INotifyCollectionChanged
eventi generati da queste classi - quindi sta a voi come uno sviluppatore di marshall questi cambiamenti .
Il motivo: ObservableCollection
esiste nelle basi di codice MS e Mono, quindi non è facile che MvvmCross possa modificare queste implementazioni esistenti.
io non sono del tutto sicuro nella vittoria-phone, ma si può usare il 'Application.Current.Dispatcher' per invocare l'aggiornamento? O sarebbe 'Deployment.Current.Dispatcher'? –