wszystkich platformach MvvmCross wymagają UI-actions się marshalled powrotem na UI Temat/Apartament - ale każda platforma robi to inaczej ....
Aby obejść ten problem, MvvmCross zapewnia sposób wieloplatformowe w tym celu - przy użyciu obiektu, któremu wstrzyknięto IMvxViewDispatcherProvider
.
Na przykład, na WindowsPhone IMvxViewDispatcherProvider
jest ostatecznie przez MvxMainThreadDispatcher
w https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxMainThreadDispatcher.cs
ten realizuje InvokeOnMainThread
używając:
private bool InvokeOrBeginInvoke(Action action)
{
if (_uiDispatcher.CheckAccess())
action();
else
_uiDispatcher.BeginInvoke(action);
return true;
}
Dla kodu w ViewModels:
- Twój
ViewModel
dziedziczy z MvxViewModel
- z
MvxViewModel
dziedziczy an MvxApplicationObject
- z
MvxApplicationObject
dziedziczy z MvxNotifyPropertyChanged
- przedmiotem
MvxNotifyPropertyChanged
dziedziczy z MvxMainThreadDispatchingObject
MvxMainThreadDispatchingObject
jest 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);
}
}
Więc ... Twój widok Model może po prostu zadzwoń InvokeOnMainThread(() => DoStuff());
jeden dodatkowy punkt, aby pamiętać, że MvvmCross automatycznie wykonuje konwersje wątku UI aktualizacje własności, które sygnalizowane są w MvxViewModel
(czy rzeczywiście w każdym MvxNotifyPropertyChanged
obiektu) za pomocą metod RaisePropertyChanged()
- patrz:
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));
});
}
w https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/ViewModels/MvxNotifyPropertyChanged.cs
This automatyczne rozkazy połączeń RaisePropertyChanged()
działają dobrze w większości sytuacji, ale mogą być nieco nieefektywne, jeśli podnosisz wiele zmienionych właściwości z wątku tła - może to prowadzić do znacznego przełączania kontekstu wątków. To nie jest coś, co trzeba mieć świadomość w większości kodzie - ale jeśli kiedykolwiek zrobić uważają, że jest to problem, to może pomóc zmienić kod tak:
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
do:
InvokeOnMainThread(() => {
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
});
Jeśli kiedykolwiek użyć ObservableCollection
, to należy pamiętać, że MvvmCross robi nie robić żadnych wątek punkt etapowy dla INotifyPropertyChanged
lub INotifyCollectionChanged
wydarzeń opalanych tych klas - tak to do Ciebie jako programista Marshall te zmiany .
Powód: ObservableCollection
istnieje w bazach kodów MS i Mono - więc nie ma łatwego sposobu, aby MvvmCross mógł zmienić te istniejące implementacje.
Nie jestem całkowicie pewny w telefonie z wygraną, ale czy można użyć 'Application.Current.Dispatcher' do wywołania aktualizacji? Czy może to być 'Deployment.Current.Dispatcher'? –