我在应用程序中使用的是Autofac版本4.9.2。以下是导航顺序:
SplashView->LoginView->MainView
MainView是包含4个选项卡菜单的选项卡式页面。点击每个菜单项时,将调用相应页面,但未调用ViewModel。
我已经在Locator类中注册了每个ViewModel类,还添加了每个ViewModel相对于其View的映射。
定位器类
public class Locator
{
IContainer container;
ContainerBuilder containerBuilder;
public static Locator Instance { get; } = new Locator();
public Locator()
{
containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<NavigationService>().As<INavigationService>();
containerBuilder.RegisterType<RequestService>().As<IRequestService>();
containerBuilder.RegisterType<SplashViewModel>();
containerBuilder.RegisterType<LoginViewModel>();
containerBuilder.RegisterType<MainViewModel>();
containerBuilder.RegisterType<Tab1ViewModel>();
containerBuilder.RegisterType<Tab2ViewModel>();
containerBuilder.RegisterType<Tab3ViewModel>();
containerBuilder.RegisterType<Tab4ViewModel>();
}
public T Resolve<T>() => container.Resolve<T>();
public object Resolve(Type type) => container.Resolve(type);
public void Register<TInterface, TImplementation>() where TImplementation : TInterface => containerBuilder.RegisterType<TImplementation>().As<TInterface>();
public void Register<T>() where T : class => containerBuilder.RegisterType<T>();
public void Build() => container = containerBuilder.Build();
}
NavigationService类:
public class NavigationService : INavigationService
{
readonly IAuthenticationService authenticationService;
protected readonly Dictionary<Type, Type> mappings;
protected Application CurrentApplication => Application.Current;
public NavigationService()
{
mappings = new Dictionary<Type, Type>();
CreatePageViewModelMappings();
}
public async Task InitializeAsync()
{
await NavigateToAsync<LoginViewModel>();
}
public async Task NavigateBackAsync()
{
if (CurrentApplication.MainPage is MainView)
{
var mainPage = CurrentApplication.MainPage as MainView;
await mainPage.Navigation.PopAsync();
}
else if (CurrentApplication.MainPage != null)
{
await CurrentApplication.MainPage.Navigation.PopAsync();
}
}
public Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase=> InternalNavigateToAsync(typeof(TViewModel), null);
public Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase=> InternalNavigateToAsync(typeof(TViewModel), parameter);
public Task NavigateToAsync(Type viewModelType) => InternalNavigateToAsync(viewModelType, null);
public Task NavigateToAsync(Type viewModelType, object parameter) => InternalNavigateToAsync(viewModelType, parameter);
public virtual Task RemoveLastFromBackStackAsync()
{
if (CurrentApplication.MainPage is MainView mainPage)
{
mainPage.Navigation.RemovePage(
mainPage.Navigation.NavigationStack[mainPage.Navigation.NavigationStack.Count - 2]);
}
return Task.FromResult(true);
}
protected Page CreateAndBindPage(Type viewModelType, object parameter)
{
var pageType = GetPageTypeForViewModel(viewModelType);
if (pageType == null)
{
throw new Exception($"Mapping type for {viewModelType} is not a page");
}
var page = Activator.CreateInstance(pageType) as Page;
var viewModel = Locator.Instance.Resolve(viewModelType) as ViewModelBase;
page.BindingContext = viewModel;
return page;
}
void CreatePageViewModelMappings()
{
mappings.Add(typeof(SplashViewModel), typeof(SplashView));
mappings.Add(typeof(LoginViewModel), typeof(LoginView));
mappings.Add(typeof(MainViewModel), typeof(MainView));
mappings.Add(typeof(Tab1ViewModel), typeof(Tab1View));
mappings.Add(typeof(Tab2ViewModel), typeof(Tab2View));
mappings.Add(typeof(Tab3ViewModel), typeof(Tab3View));
mappings.Add(typeof(Tab4ViewModel), typeof(Tab4View));
}
}
MainView xaml:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:page="clr-namespace:SampleApp.Views;assembly=SampleApp"
x:Class="SampleApp.Views.MainView">
<page:Tab1View Title="Tab1" Icon="tab1.png"/>
<page:Tab2View Title="Tab2" Icon="tab2.png"/>
<page:Tab3View Title="Tab3" Icon="tab3.png"/>
<page:Tab4View Title="Tab4" Icon="tab4.png"/>
</TabbedPage>
LoginViewModel:
成功登录后:
await NavigationService.NavigateToAsync<MainViewModel>();