问题
I am taking over an application developed with MvvmCross.vNext.
While trying to update it with MvvmCross.V3, I found the following breaking change: in the constructor of the MainViewModel, we show the LoginViewModel (ShowViewModel()).
It worked fine in vNext.
But with V3, the LoginView doesn't show.
After a long search, I found out that the following code, added in MvxStoreMainThreadDispatcher.RequestMainThreadAction :
if (_uiDispatcher.HasThreadAccess)
{
action();
return true;
}
was responsible for my troubles.
If I comment it out, my application works as previously, but I guess this code is there for some reasons...
Do you have any suggestions ?
Can I force the previous behavior without changing MvvmCross source code?
Should I refactor the code to handle the LoginView differently ?
Thanks in advance for your comments.
Philippe
回答1:
While trying to update it with MvvmCross.V3, I found the following breaking change: in the constructor of the MainViewModel, we show the LoginViewModel (ShowViewModel()). It worked fine in vNext.
I think your constructor navigation would have broken on several platforms in any MvvmCross version. To be honest, I think you were lucky it worked before.
The problem is that ViewModels are constructed (or located) during View events such as ViewDidLoad
, OnNavigatedTo
, and OnCreate
- and these events are normally
called during 'page transitions'
To work around this you will need to move your login navigation out of the constructor.
How you do this depends on your app
if you do need the Home->Login backstack, then you can trigger off some async or time delay or you can trigger off some other View event such as something like
ViewDidAppear
if you don't need that backstack then the way I normally implement this sort of thing is to use a custom
IMvxAppStart
- something like:public class AppStart : MvxNavigatingObject , IMvxAppStart { public void Start(object hint = null) { var authService = Mvx.Resolve<IMySerice>(); if (authService.IsLoggedIn) { ShowViewModel<HomeViewModel>(); } else { ShowViewModel<LoginViewModel>(); } } }
(you can see another example in https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CirriousConference/Cirrious.Conference.Core/ApplicationObjects/AppStart.cs)
This can be registered in App.cs startup using:
RegisterAppStart(new AppStart());
来源:https://stackoverflow.com/questions/16100110/coredispatcher-hasthreadaccess-breaking-change