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)); } }; }
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); }
public TabBar() { Shell.SetFlyoutBehavior(this, FlyoutBehavior.Disabled); }
public FlyoutItem() { Shell.SetFlyoutBehavior(this, FlyoutBehavior.Flyout); }