Skip to content

Instantly share code, notes, and snippets.

@chris84948
Created June 30, 2017 19:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chris84948/24249b213ae17df62b3b552dc2b74d37 to your computer and use it in GitHub Desktop.
Save chris84948/24249b213ae17df62b3b552dc2b74d37 to your computer and use it in GitHub Desktop.
Navigation service for ViewModel first navigation in Xamarin
using LiteSourceGo.ViewModels;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms;
public class Navigator
{
static Navigator instance;
public static Navigator Instance
{
get { return instance ?? (instance = new Navigator()); }
}
INavigation FormsNavigation
{
get { return Application.Current.MainPage.Navigation; }
}
readonly Dictionary<Type, Type> _viewModelViewDictionary = new Dictionary<Type, Type>();
public void Register(Type viewModelType, Type viewType)
{
if (!_viewModelViewDictionary.ContainsKey(viewModelType))
_viewModelViewDictionary.Add(viewModelType, viewType);
}
public async Task PopAsync()
{
await FormsNavigation.PopAsync(true);
}
public async Task PopModalAsync()
{
await FormsNavigation.PopModalAsync(true);
}
public async Task PopToRootAsync(bool animate)
{
await FormsNavigation.PopToRootAsync(animate);
}
public void PopTo<T>() where T : BaseViewModel
{
var pagesToRemove = new List<Page>();
for (int i = FormsNavigation.NavigationStack.Count - 1; i >= 0; i--)
{
var currentPage = FormsNavigation.NavigationStack[i] as Page;
if (currentPage?.BindingContext.GetType() == typeof(T))
break;
pagesToRemove.Add(currentPage);
}
foreach (var page in pagesToRemove)
FormsNavigation.RemovePage(page);
}
public async Task PushAsync<T>(T viewModel) where T : BaseViewModel
{
var view = InstantiateView(viewModel);
await FormsNavigation.PushAsync((Page)view);
}
public async Task PushModalAsync<T>(T viewModel) where T : BaseViewModel
{
var view = InstantiateView(viewModel);
var nv = new NavigationPage(view);
await FormsNavigation.PushModalAsync(nv);
}
Page InstantiateView<T>(T viewModel) where T : BaseViewModel
{
var viewModelType = viewModel.GetType();
var view = (Page)GetViewType(viewModelType);
view.BindingContext = viewModel;
return view;
}
private object GetViewType(Type viewModelType)
{
Type viewType = null;
if (_viewModelViewDictionary.ContainsKey(viewModelType))
{
viewType = _viewModelViewDictionary[viewModelType];
}
else
{
string viewTypeName = viewModelType.FullName.Replace("ViewModel", "View");
viewType = Type.GetType(viewTypeName);
// We don't have it already, get it now, and add it to the dictionary
_viewModelViewDictionary.Add(viewModelType, viewType);
}
return Activator.CreateInstance(viewType);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment