Я использую Autofac версии 4.9.2 в моем приложении.Ниже приведена последовательность навигации:
SplashView->LoginView->MainView
MainView - страница с вкладками, содержащая меню с 4 вкладками.При нажатии на каждый пункт меню вызывается соответствующая страница, но ее ViewModel не вызывается.
Я зарегистрировал каждый класс ViewModel в классе Locator, а также добавил отображение каждой 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>();