Toutes les plates-formes MvvmCross exigent que les actions de l'interface utilisateur-get rassemblèrent retour à l'interface utilisateur Discussion/Appartement - mais chaque plate-forme ne différemment ....
Pour contourner ce problème, MvvmCross fournit un moyen multi-plateforme pour ce faire - en utilisant un objet injecté IMvxViewDispatcherProvider
.
Par exemple, sur Windows Phone IMvxViewDispatcherProvider
est fourni en fin de compte par MvxMainThreadDispatcher
dans https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxMainThreadDispatcher.cs
Ceci implémente l'InvokeOnMainThread
en utilisant:
private bool InvokeOrBeginInvoke(Action action)
{
if (_uiDispatcher.CheckAccess())
action();
else
_uiDispatcher.BeginInvoke(action);
return true;
}
Pour le code dans ViewModels:
- votre
ViewModel
hérite de MvxViewModel
- les
MvxViewModel
hérite d'un MvxApplicationObject
- les
MvxApplicationObject
hérite d'un MvxNotifyPropertyChanged
- l'objet
MvxNotifyPropertyChanged
hérite d'un MvxMainThreadDispatchingObject
MvxMainThreadDispatchingObject
est 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);
}
}
Alors ... ta vue Modèle peut simplement appeler le InvokeOnMainThread(() => DoStuff());
Un autre point à noter est que MvvmCross effectue automatiquement les conversions de thread d'interface utilisateur pour les mises à jour de propriété qui sont signalés dans un MvxViewModel
(ou bien dans un objet MvxNotifyPropertyChanged
) à travers les RaisePropertyChanged()
méthodes - voir:
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));
});
}
dans https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/ViewModels/MvxNotifyPropertyChanged.cs
Cette Le regroupement automatique des appels RaisePropertyChanged()
fonctionne bien dans la plupart des cas, mais peut s'avérer un peu inefficace si vous augmentez un grand nombre de propriétés modifiées à partir d'un thread d'arrière-plan - cela peut entraîner un grand nombre de changements de contexte de threads. Ce n'est pas quelque chose que vous devez être au courant dans la plupart de votre code - mais si vous ne trouvez jamais il y a un problème, il peut aider à modifier le code comme:
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
à:
InvokeOnMainThread(() => {
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
});
Si vous utilisez jamais ObservableCollection
, alors s'il vous plaît noter que MvvmCross ne pas faire un thread pour les marshalling tirés par ces classes INotifyPropertyChanged
ou INotifyCollectionChanged
événements - il est donc à vous en tant que développeur pour marshall ces changements .
La raison: ObservableCollection
existe dans les bases de code MS et Mono - il n'y a donc pas de manière simple que MvvmCross puisse changer ces implémentations existantes.
Je ne suis pas entièrement sûr dans win-phone, mais pouvez-vous utiliser 'Application.Current.Dispatcher' pour invoquer la mise à jour? Ou serait-ce 'Deployment.Current.Dispatcher'? –