Example #1
0
        public ShellHandler(NativeComponentRenderer renderer, XF.Shell shellControl) : base(renderer, shellControl)
        {
            ShellControl = shellControl ?? throw new ArgumentNullException(nameof(shellControl));

            // Add one item for Shell to load correctly. It will later be removed when the first real
            // item is added by the app.
            ShellControl.Items.Add(_dummyShellContent);

            // Add a dummy FlyoutHeader because it cannot be set dynamically later. When app code sets
            // its own FlyoutHeader, it will be set as the Content of this ContentView.
            // See https://github.com/xamarin/Xamarin.Forms/issues/6161 ([Bug] Changing the Shell Flyout Header after it's already rendered doesn't work)
            _flyoutHeaderContentView.IsVisible = false;
            ShellControl.FlyoutHeader          = _flyoutHeaderContentView;

            ShellControl.Navigated += (s, e) =>
            {
                if (NavigatedEventHandlerId != default)
                {
                    renderer.Dispatcher.InvokeAsync(() => renderer.DispatchEventAsync(NavigatedEventHandlerId, null, e));
                }
            };
            ShellControl.Navigating += (s, e) =>
            {
                if (NavigatingEventHandlerId != default)
                {
                    renderer.Dispatcher.InvokeAsync(() => renderer.DispatchEventAsync(NavigatingEventHandlerId, null, e));
                }
            };
        }
Example #2
0
        static Page GetCurrentPage(XShell shell)
        {
            var stack       = (shell.CurrentItem.CurrentItem as ShellSection)?.Stack;
            var currentPage = stack?.LastOrDefault <Page>();

            if (currentPage == null)
            {
                currentPage = (shell.CurrentItem.CurrentItem.CurrentItem as IShellContentController)?.Page;
            }
            return(currentPage);
        }
 private static ElementHandler CreateHandler(XF.Element parent, MobileBlazorBindingsRenderer renderer)
 {
     return(parent switch
     {
         XF.ContentPage contentPage => new ContentPageHandler(renderer, contentPage),
         XF.ContentView contentView => new ContentViewHandler(renderer, contentView),
         XF.Label label => new LabelHandler(renderer, label),
         XF.FlyoutPage flyoutPage => new FlyoutPageHandler(renderer, flyoutPage),
         XF.ScrollView scrollView => new ScrollViewHandler(renderer, scrollView),
         XF.ShellContent shellContent => new ShellContentHandler(renderer, shellContent),
         XF.Shell shell => new ShellHandler(renderer, shell),
         XF.ShellItem shellItem => new ShellItemHandler(renderer, shellItem),
         XF.ShellSection shellSection => new ShellSectionHandler(renderer, shellSection),
         XF.TabbedPage tabbedPage => new TabbedPageHandler(renderer, tabbedPage),
         _ => new ElementHandler(renderer, parent),
     });
        public ShellHandler(NativeComponentRenderer renderer, XF.Shell shellControl) : base(renderer, shellControl)
        {
            ShellControl = shellControl ?? throw new ArgumentNullException(nameof(shellControl));

            Initialize(renderer);
        }
		public static Uri ConvertToStandardFormat(Shell shell, Uri request)
		{
			request = FormatUri(request, shell);
			return ConvertToStandardFormat(shell?.RouteScheme, shell?.RouteHost, shell?.Route, request);
		}
		internal static List<RouteRequestBuilder> GenerateRoutePaths(Shell shell, Uri request, Uri originalRequest, bool enableRelativeShellRoutes)
		{
			var routeKeys = Routing.GetRouteKeys();
			for (int i = 0; i < routeKeys.Length; i++)
			{
				if (routeKeys[i] == originalRequest.OriginalString)
				{
					var builder = new RouteRequestBuilder(routeKeys[i], routeKeys[i], null, new string[] { routeKeys[i] });
					return new List<RouteRequestBuilder> { builder };
				}
				routeKeys[i] = FormatUri(routeKeys[i]);
			}

			request = FormatUri(request, shell);
			originalRequest = FormatUri(originalRequest, shell);

			List<RouteRequestBuilder> possibleRoutePaths = new List<RouteRequestBuilder>();
			if (!request.IsAbsoluteUri)
				request = ConvertToStandardFormat(shell, request);

			string localPath = request.LocalPath;

			bool relativeMatch = false;
			if (!originalRequest.IsAbsoluteUri &&
				!originalRequest.OriginalString.StartsWith("//", StringComparison.Ordinal))
				relativeMatch = true;

			var segments = localPath.Split(_pathSeparator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

			if (!relativeMatch)
			{
				for (int i = 0; i < routeKeys.Length; i++)
				{
					var route = routeKeys[i];
					var uri = ConvertToStandardFormat(shell, CreateUri(route));
					if (uri.Equals(request))
					{
						throw new Exception($"Global routes currently cannot be the only page on the stack, so absolute routing to global routes is not supported. For now, just navigate to: {originalRequest.OriginalString.Replace("//", "")}");
						//var builder = new RouteRequestBuilder(route, route, null, segments);
						//return new List<RouteRequestBuilder> { builder };
					}
				}
			}

			var depthStart = 0;

			if (segments[0] == shell?.Route)
			{
				segments = segments.Skip(1).ToArray();
				depthStart = 1;
			}
			else
			{
				depthStart = 0;
			}

			if (relativeMatch && shell?.CurrentItem != null)
			{
				// retrieve current location
				var currentLocation = NodeLocation.Create(shell);

				while (currentLocation.Shell != null)
				{
					var pureRoutesMatch = new List<RouteRequestBuilder>();
					var pureGlobalRoutesMatch = new List<RouteRequestBuilder>();

					//currently relative routes to shell routes isn't supported as we aren't creating navigation stacks
					if (enableRelativeShellRoutes)
					{
						SearchPath(currentLocation.LowestChild, null, segments, pureRoutesMatch, 0);
						ExpandOutGlobalRoutes(pureRoutesMatch, routeKeys);
						pureRoutesMatch = GetBestMatches(pureRoutesMatch);
						if (pureRoutesMatch.Count > 0)
						{
							return pureRoutesMatch;
						}
					}


					SearchPath(currentLocation.LowestChild, null, segments, pureGlobalRoutesMatch, 0, ignoreGlobalRoutes: false);
					ExpandOutGlobalRoutes(pureGlobalRoutesMatch, routeKeys);
					pureGlobalRoutesMatch = GetBestMatches(pureGlobalRoutesMatch);
					if (pureGlobalRoutesMatch.Count > 0)
					{
						// currently relative routes to shell routes isn't supported as we aren't creating navigation stacks
						// So right now we will just throw an exception so that once this is implemented
						// GotoAsync doesn't start acting inconsistently and all of a sudden starts creating routes

						int shellElementsMatched = 
							pureGlobalRoutesMatch[0].SegmentsMatched.Count -
							pureGlobalRoutesMatch[0].GlobalRouteMatches.Count;

						if (!enableRelativeShellRoutes && shellElementsMatched > 0)
						{
							throw new Exception($"Relative routing to shell elements is currently not supported. Try prefixing your uri with ///: ///{originalRequest}");
						}

						return pureGlobalRoutesMatch;
					}

					currentLocation.Pop();
				}

				string searchPath = String.Join(_pathSeparator, segments);

				if (routeKeys.Contains(searchPath))
				{
					return new List<RouteRequestBuilder> { new RouteRequestBuilder(searchPath, searchPath, null, segments) };
				}

				RouteRequestBuilder builder = null;
				foreach (var segment in segments)
				{
					if (routeKeys.Contains(segment))
					{
						if (builder == null)
							builder = new RouteRequestBuilder(segment, segment, null, segments);
						else
							builder.AddGlobalRoute(segment, segment);
					}
				}

				if (builder != null && builder.IsFullMatch)
					return new List<RouteRequestBuilder> { builder };
			}
			else
			{
				possibleRoutePaths.Clear();
				SearchPath(shell, null, segments, possibleRoutePaths, depthStart);

				var bestMatches = GetBestMatches(possibleRoutePaths);
				if (bestMatches.Count > 0)
					return bestMatches;

				bestMatches.Clear();
				ExpandOutGlobalRoutes(possibleRoutePaths, routeKeys);
			}

			possibleRoutePaths = GetBestMatches(possibleRoutePaths);
			return possibleRoutePaths;
		}
		internal static List<RouteRequestBuilder> GenerateRoutePaths(Shell shell, Uri request)
		{
			request = FormatUri(request, shell);
			return GenerateRoutePaths(shell, request, request, false);
		}
Example #8
0
 public TabBar()
 {
     Shell.SetFlyoutBehavior(this, FlyoutBehavior.Disabled);
 }
Example #9
0
 public FlyoutItem()
 {
     Shell.SetFlyoutBehavior(this, FlyoutBehavior.Flyout);
 }