private async Task <bool> NavigateTo(Type type, object param, bool push) { // Do we already have a ViewModel? If so we check if we can navigate await. // This logic is there to add the possibility of blocking navigation if data is dirty. if (_current != null) { if (!_current.BeforeNavigationAway()) { return(false); } } IViewModel vm = null; var oldView = _currentView; // Create an instance of the object type passed in the navigation. //var vobj = _mvvmConfiguration.IoC.Resolve(type); if (typeof(IView).IsAssignableFrom(type) && !IgnoreView) { // if it's a View, we get the corresponding ViewModel. _currentView = _mvvmConfiguration.IoC.Resolve(type) as IView; vm = GetViewModelForView(_currentView); } else { // It was a ViewModel, let's get the corresponding View. vm = (IViewModel)_mvvmConfiguration.IoC.Resolve(type); if (!IgnoreView) { _currentView = GetViewFromViewModel(vm); } } if (vm == null || (_currentView == null && !IgnoreView)) { throw new ArgumentException("Type is not a navigation type for this framework"); } // We set the ViewModel as the DataContext of the View for bindings. if (!IgnoreView) { (_currentView as UserControl).DataContext = vm; } // Add Navigator to both if (!IgnoreView) { _currentView.Nav = this; } vm.Navigator = this; // If View has a ModelView property, then set it. if (!IgnoreView) { var prop = _currentView.GetType().GetProperty("ModelView"); if (prop != null) { prop.SetValue(_currentView, vm); } } vm.BeforeNavigationTo(); if (_current != null && push) { _breadcrumb.Push(_currentStamp); } if (_current != null) { _current.NavigatedAway(); } if (oldView != null) { oldView.ViewUnloaded(); } _mvvmConfiguration.SetOnNavigation(_currentView, vm); if (!await vm.NavigatedTo(param)) { _currentView = null; _current = null; await GoBack(); return(false); } if (!IgnoreView) { _currentView.ViewLoaded(); } if (OnCreateStamp != null) { OnCreateStamp(_currentStamp); } _currentStamp = new NavigationStamp() { Param = param, ViewModel = vm.GetType() }; _current = vm; //trigger navigation finished event with success value if (NavigationFinished != null) { NavigationFinished(this, true); } return(true); }