public virtual void AddChild(XF.Element child, int physicalSiblingIndex) { if (child is null) { throw new ArgumentNullException(nameof(child)); } XF.ShellSection sectionToAdd = child switch { XF.TemplatedPage childAsTemplatedPage => childAsTemplatedPage, // Implicit conversion XF.ShellContent childAsShellContent => childAsShellContent, // Implicit conversion XF.ShellSection childAsShellSection => childAsShellSection, _ => throw new NotSupportedException($"Handler of type '{GetType().FullName}' representing element type '{TargetElement?.GetType().FullName ?? "<null>"}' doesn't support adding a child (child type is '{child.GetType().FullName}').") }; if (ShellItemControl.Items.Count >= physicalSiblingIndex) { ShellItemControl.Items.Insert(physicalSiblingIndex, sectionToAdd); } else { Debug.WriteLine($"WARNING: {nameof(AddChild)} called with {nameof(physicalSiblingIndex)}={physicalSiblingIndex}, but ShellItemControl.Items.Count={ShellItemControl.Items.Count}"); ShellItemControl.Items.Add(sectionToAdd); } }
private XF.ShellSection GetSectionForElement(XF.Element child) { return(child switch { XF.TemplatedPage childAsTemplatedPage => GetSectionForTemplatedPage(childAsTemplatedPage), XF.ShellContent childAsShellContent => GetSectionForContent(childAsShellContent), XF.ShellSection childAsShellSection => childAsShellSection, _ => null });
private XF.ShellItem GetItemForElement(XF.Element child) { return(child switch { XF.TemplatedPage childAsTemplatedPage => GetItemForTemplatedPage(childAsTemplatedPage), XF.ShellContent childAsShellContent => GetItemForContent(childAsShellContent), XF.ShellSection childAsShellSection => GetItemForSection(childAsShellSection), XF.MenuItem childAsMenuItem => GetItemForMenuItem(childAsMenuItem), XF.ShellItem childAsShellItem => childAsShellItem, _ => null });
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 virtual void RemoveChild(XF.Element child) { if (child is null) { throw new ArgumentNullException(nameof(child)); } var sectionToRemove = child switch { XF.TemplatedPage childAsTemplatedPage => GetSectionForTemplatedPage(childAsTemplatedPage), XF.ShellContent childAsShellContent => GetSectionForContent(childAsShellContent), XF.ShellSection childAsShellSection => childAsShellSection, _ => throw new NotSupportedException($"Handler of type '{GetType().FullName}' representing element type '{TargetElement?.GetType().FullName ?? "<null>"}' doesn't support removing a child (child type is '{child.GetType().FullName}').") }; ShellItemControl.Items.Remove(sectionToRemove); }
internal static ShellItem GetShellItemFromRouteName(string route) { var shellContent = new ShellContent { Route = route, Content = Routing.GetOrCreateContent(route) }; var result = new ShellItem(); var shellSection = new ShellSection(); shellSection.Items.Add(shellContent); result.Route = Routing.GenerateImplicitRoute(shellSection.Route); result.Items.Add(shellSection); result.SetBinding(TitleProperty, new Binding(nameof(Title), BindingMode.OneWay, source: shellSection)); result.SetBinding(IconProperty, new Binding(nameof(Icon), BindingMode.OneWay, source: shellSection)); result.SetBinding(FlyoutDisplayOptionsProperty, new Binding(nameof(FlyoutDisplayOptions), BindingMode.OneTime, source: shellSection)); result.SetBinding(FlyoutIconProperty, new Binding(nameof(FlyoutIcon), BindingMode.OneWay, source: shellSection)); return(result); }
bool IShellItemController.ProposeSection(ShellSection shellSection, bool setValue) { var controller = (IShellController)Parent; if (controller == null) return false; bool accept = controller.ProposeNavigation(ShellNavigationSource.ShellSectionChanged, this, shellSection, shellSection?.CurrentItem, shellSection?.Stack, true ); if (accept && setValue) SetValueFromRenderer(CurrentItemProperty, shellSection); return accept; }
// This is used for cases where the user is navigating via native UI navigation i.e. clicking on Tabs // If the user defers this type of navigation we generate the equivalent GotoAsync call // so when the deferral is completed the same navigation can complete public bool ProposeNavigationOutsideGotoAsync( ShellNavigationSource source, ShellItem shellItem, ShellSection shellSection, ShellContent shellContent, IReadOnlyList <Page> stack, bool canCancel, bool isAnimated) { if (_accumulateNavigatedEvents) { return(true); } var proposedState = GetNavigationState(shellItem, shellSection, shellContent, stack, shellSection.Navigation.ModalStack); var navArgs = ProposeNavigation(source, proposedState, canCancel, isAnimated); if (navArgs.DeferralCount > 0) { navArgs.RegisterDeferralCompletedCallBack(async() => { if (navArgs.Cancelled) { return; } Func <Task> navigationTask = () => GoToAsync(navArgs.Target, navArgs.Animate, false, navArgs); if (Device.IsInvokeRequired) { await Device.InvokeOnMainThreadAsync(navigationTask); } else { await navigationTask(); } }); } return(!navArgs.NavigationDelayedOrCancelled); }
internal static ShellItem CreateFromShellSection(ShellSection shellSection) { ShellItem result = null; if (shellSection is Tab) { result = new TabBar(); } else { result = new ShellItem(); } result.Route = Routing.GenerateImplicitRoute(shellSection.Route); result.Items.Add(shellSection); result.SetBinding(TitleProperty, new Binding(nameof(Title), BindingMode.OneWay, source: shellSection)); result.SetBinding(IconProperty, new Binding(nameof(Icon), BindingMode.OneWay, source: shellSection)); result.SetBinding(FlyoutDisplayOptionsProperty, new Binding(nameof(FlyoutDisplayOptions), BindingMode.OneTime, source: shellSection)); return(result); }
public ShellSectionHandler(NativeComponentRenderer renderer, XF.ShellSection shellSectionControl) : base(renderer, shellSectionControl) { ShellSectionControl = shellSectionControl ?? throw new ArgumentNullException(nameof(shellSectionControl)); Initialize(renderer); }
public RequestDefinition(string fullUri, ShellItem item, ShellSection section, ShellContent content, List <string> globalRoutes) : this(new Uri(fullUri, UriKind.Absolute), item, section, content, globalRoutes) { }
public static ShellNavigationState GetNavigationState(ShellItem shellItem, ShellSection shellSection, ShellContent shellContent, IReadOnlyList <Page> sectionStack, IReadOnlyList <Page> modalStack) { List <string> routeStack = new List <string>(); bool stackAtRoot = sectionStack == null || sectionStack.Count <= 1; bool hasUserDefinedRoute = (Routing.IsUserDefined(shellItem)) || (Routing.IsUserDefined(shellSection)) || (Routing.IsUserDefined(shellContent)); if (shellItem != null) { var shellItemRoute = shellItem.Route; routeStack.Add(shellItemRoute); if (shellSection != null) { var shellSectionRoute = shellSection.Route; routeStack.Add(shellSectionRoute); if (shellContent != null) { var shellContentRoute = shellContent.Route; routeStack.Add(shellContentRoute); } if (!stackAtRoot) { for (int i = 1; i < sectionStack.Count; i++) { var page = sectionStack[i]; routeStack.AddRange(CollapsePath(Routing.GetRoute(page), routeStack, hasUserDefinedRoute)); } } if (modalStack != null && modalStack.Count > 0) { for (int i = 0; i < modalStack.Count; i++) { var topPage = modalStack[i]; routeStack.AddRange(CollapsePath(Routing.GetRoute(topPage), routeStack, hasUserDefinedRoute)); for (int j = 1; j < topPage.Navigation.NavigationStack.Count; j++) { routeStack.AddRange(CollapsePath(Routing.GetRoute(topPage.Navigation.NavigationStack[j]), routeStack, hasUserDefinedRoute)); } } } } } if (routeStack.Count > 0) { routeStack.Insert(0, "/"); } return(new ShellNavigationState(String.Join("/", routeStack), true)); List <string> CollapsePath( string myRoute, IEnumerable <string> currentRouteStack, bool userDefinedRoute) { var localRouteStack = currentRouteStack.ToList(); for (var i = localRouteStack.Count - 1; i >= 0; i--) { var route = localRouteStack[i]; if (Routing.IsImplicit(route) || (Routing.IsDefault(route) && userDefinedRoute)) { localRouteStack.RemoveAt(i); } } var paths = myRoute.Split('/').ToList(); // collapse similar leaves int walkBackCurrentStackIndex = localRouteStack.Count - (paths.Count - 1); while (paths.Count > 1 && walkBackCurrentStackIndex >= 0) { if (paths[0] == localRouteStack[walkBackCurrentStackIndex]) { paths.RemoveAt(0); } else { break; } walkBackCurrentStackIndex++; } return(paths); } }
private XF.ShellItem GetItemForSection(XF.ShellSection childAsShellSection) { return(ShellControl.Items.FirstOrDefault(item => item.Items.Contains(childAsShellSection))); }