private static bool HasViewModel(object view, Type viewModelType)
        {
            if (view == null)
            {
                return(false);
            }
            var viewModel = ToolkitExtensions.GetDataContext(view) as IViewModel;

            if (viewModel == null)
            {
                return(false);
            }

            var vmType = viewModel.GetType();

#if WINDOWS_UWP || XAMARIN_FORMS
            if (!viewModelType.GetTypeInfo().IsGenericType)
#else
            if (!viewModelType.IsGenericType)
#endif
            { return(vmType.Equals(viewModelType)); }
#if WINDOWS_UWP || XAMARIN_FORMS
            if (!vmType.GetTypeInfo().IsGenericType)
#else
            if (!vmType.IsGenericType)
#endif
            { return(false); }
            return(vmType.GetGenericTypeDefinition().Equals(viewModelType.GetGenericTypeDefinition()));
        }
        public bool CanClose(IDataContext dataContext)
        {
            Should.NotBeNull(dataContext, nameof(dataContext));
            var viewModel = dataContext.GetData(NavigationConstants.ViewModel);

            if (viewModel == null)
            {
                return(false);
            }

            var content  = CurrentContent;
            var canClose = content != null && ToolkitExtensions.GetDataContext(content) == viewModel && _frame.CanGoBack;

            if (canClose)
            {
                return(true);
            }
            var viewModelId = viewModel.GetViewModelId();
            var backStack   = _frame.BackStack;

            for (int index = 0; index < backStack.Count; index++)
            {
                if (GetViewModelIdFromParameter(backStack[index].Parameter) == viewModelId)
                {
                    return(true);
                }
            }
            return(false);
        }
        public bool TryClose(IDataContext dataContext)
        {
            Should.NotBeNull(dataContext, nameof(dataContext));
            var viewModel = dataContext.GetData(NavigationConstants.ViewModel);

            if (viewModel == null)
            {
                return(false);
            }

            var content = CurrentContent;

            if (content != null && ToolkitExtensions.GetDataContext(content) == viewModel && _frame.CanGoBack)
            {
                _lastContext = dataContext;
                _frame.GoBack();
                return(true);
            }

            if (!CanClose(dataContext))
            {
                return(false);
            }

            if (RaiseNavigatingRemove(dataContext))
            {
                bool closed      = false;
                var  viewModelId = viewModel.GetViewModelId();
                for (int index = 0; index < _frame.BackStack.Count; index++)
                {
                    if (GetViewModelIdFromParameter(_frame.BackStack[index].Parameter) == viewModelId)
                    {
                        _frame.BackStack.RemoveAt(index);
                        --index;
                        closed = true;
                    }
                }
                if (closed)
                {
                    RaiseNavigated(new RemoveNavigationEventArgs(dataContext));
                }
                return(closed);
            }
            return(true);
        }
        protected virtual IViewModel GetViewModelForView([NotNull] NavigationEventArgsBase args,
                                                         [CanBeNull] IViewModel navigationViewModel, [NotNull] INavigationContext context, [NotNull] Type vmType)
        {
            var view = args.Content;

            if (navigationViewModel != null)
            {
                ViewManager.InitializeViewAsync(navigationViewModel, view, context);
                return(navigationViewModel);
            }


            if (HasViewModel(view, vmType))
            {
                return((IViewModel)ToolkitExtensions.GetDataContext(view));
            }

            IDataContext viewModelState = null;

#if WINDOWS_UWP
            viewModelState = UwpToolkitExtensions.GetViewModelState(view);
            if (viewModelState != null)
            {
                UwpToolkitExtensions.SetViewModelState(view, null);
            }
#endif
            var vm = ViewModelProvider.RestoreViewModel(viewModelState, new DataContext
            {
                { InitializationConstants.ViewModelType, vmType }
            }, true);

            if (vm != null)
            {
                ViewManager.InitializeViewAsync(vm, view, context);
                if (viewModelState == null && !vm.Settings.Metadata.GetData(NavigationConstants.DoNotDisposeNoStateViewModel))
                {
                    vm.RegisterNavigationOperation(OperationType.PageNavigation, context)
                    .ContinueWith <IViewModel>((viewModel, result) => viewModel.Dispose());
                }
            }
            return(vm);
        }
Exemplo n.º 5
0
        protected virtual IViewModel GetViewModelForView([NotNull] NavigationEventArgsBase args,
                                                         [CanBeNull] IViewModel navigationViewModel, [NotNull] INavigationContext context, [NotNull] Type vmType)
        {
            var view = args.Content;

            if (navigationViewModel != null)
            {
                ViewManager.InitializeViewAsync(navigationViewModel, view, context);
                return(navigationViewModel);
            }


            if (HasViewModel(view, vmType))
            {
                return((IViewModel)ToolkitExtensions.GetDataContext(view));
            }

            IDataContext viewModelState = null;

#if WINDOWS_UWP
            viewModelState = UwpToolkitExtensions.GetViewModelState(view);
            if (viewModelState != null)
            {
                UwpToolkitExtensions.SetViewModelState(view, null);
            }
#endif
            var vm = ViewModelProvider.RestoreViewModel(viewModelState, new DataContext
            {
                { InitializationConstants.ViewModelType, vmType }
            }, true);

            if (vm != null)
            {
                ViewManager.InitializeViewAsync(vm, view, context);
            }
            return(vm);
        }
        protected virtual INavigationContext CreateContextNavigateTo(NavigationEventArgsBase args)
        {
            IViewModel viewModelFrom = null, viewModelTo = null;

            if (args.NavigationMode.IsClose())
            {
                viewModelFrom = args.Context.GetData(NavigationConstants.ViewModel);
            }
            else
            {
                viewModelTo = args.Context.GetData(NavigationConstants.ViewModel);
            }

            if (viewModelFrom == null)
            {
                viewModelFrom = CurrentViewModel;
            }
            if (args.NavigationMode == NavigationMode.Remove)
            {
                if (viewModelFrom != null)
                {
                    return(new NavigationContext(NavigationType.Page, NavigationMode.Remove, viewModelFrom, null, this, args.Context));
                }
                Tracer.Error("Possible bug in navigation, navigate with Remove mode without ViewModel");
            }

            Guid viewModelId;
            var  vmType = GetViewModelTypeFromParameter(args.Parameter, out viewModelId);

            if (viewModelTo == null && vmType != null)
            {
                viewModelTo = ViewModelProvider.TryGetViewModelById(viewModelId);
            }
            if (vmType == null)
            {
                if (args.Content != null)
                {
                    var items = ViewMappingProvider.FindMappingsForView(args.Content.GetType(), false);
                    if (items.Count == 1)
                    {
                        var type = items[0].ViewModelType;
#if WINDOWS_UWP || XAMARIN_FORMS
                        if (!type.GetTypeInfo().IsGenericTypeDefinition)
#else
                        if (!type.IsGenericTypeDefinition)
#endif

                        { vmType = type; }
                    }
                    else if (viewModelTo == null || items.Count > 1)
                    {
                        var viewModel = ToolkitExtensions.GetDataContext(args.Content) as IViewModel;
                        var type      = viewModel?.GetType();
                        if (type != null && items.Any(item => item.ViewModelType == type))
                        {
                            viewModelTo = viewModel;
                            vmType      = type;
                        }
                    }
                }
                if (vmType == null)
                {
                    return(new NavigationContext(NavigationType.Page, args.NavigationMode, viewModelFrom, viewModelTo, this, args.Context));
                }
            }
            return(new NavigationContext(NavigationType.Page, args.NavigationMode, viewModelFrom, viewModelTo, this, args.Context)
            {
                { ViewModelTypeConstant, vmType }
            });
        }