internal MenuShellItem(MenuItem menuItem) { MenuItem = menuItem; MenuItem.Parent = this; Shell.SetFlyoutItemIsVisible(this, Shell.GetFlyoutItemIsVisible(menuItem)); SetBinding(TitleProperty, new Binding(nameof(MenuItem.Text), BindingMode.OneWay, source: menuItem)); SetBinding(IconProperty, new Binding(nameof(MenuItem.IconImageSource), BindingMode.OneWay, source: menuItem)); SetBinding(FlyoutIconProperty, new Binding(nameof(MenuItem.IconImageSource), BindingMode.OneWay, source: menuItem)); SetBinding(AutomationIdProperty, new Binding(nameof(MenuItem.AutomationId), BindingMode.OneWay, source: menuItem)); MenuItem.PropertyChanged += OnMenuItemPropertyChanged; }
void OnMenuItemPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == Shell.MenuItemTemplateProperty.PropertyName) { Shell.SetMenuItemTemplate(this, Shell.GetMenuItemTemplate(MenuItem)); } else if (e.PropertyName == TitleProperty.PropertyName) { OnPropertyChanged(MenuItem.TextProperty.PropertyName); } else if (e.PropertyName == FlyoutItem.IsVisibleProperty.PropertyName) { Shell.SetFlyoutItemIsVisible(this, Shell.GetFlyoutItemIsVisible(MenuItem)); } }
bool UpdateFlyoutGroupings() { // The idea here is to create grouping such that the Flyout would // render correctly if it renderered each item in the groups in order // but put a line between the groups. This is needed because our grouping can // actually go 3 layers deep. // Ideally this lets us control where lines are drawn in the core code // just by changing how we generate these groupings var result = new List <List <Element> >(); var currentGroup = new List <Element>(); foreach (var shellItem in ShellController.GetItems()) { if (!ShowInFlyoutMenu(shellItem)) { continue; } if (Routing.IsImplicit(shellItem) || shellItem.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems) { if (shellItem.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems) { IncrementGroup(); } foreach (var shellSection in (shellItem as IShellItemController).GetItems()) { if (!ShowInFlyoutMenu(shellSection)) { continue; } var shellContents = ((IShellSectionController)shellSection).GetItems(); if (Routing.IsImplicit(shellSection) || shellSection.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems) { foreach (var shellContent in shellContents) { if (!ShowInFlyoutMenu(shellContent)) { continue; } currentGroup.Add(shellContent); if (shellContent == shellSection.CurrentItem) { AddMenuItems(shellContent.MenuItems); } } if (shellSection.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems) { IncrementGroup(); } } else { if (!(shellSection.Parent is TabBar)) { if (Routing.IsImplicit(shellSection) && shellContents.Count == 1) { if (!ShowInFlyoutMenu(shellContents[0])) { continue; } currentGroup.Add(shellContents[0]); } else { currentGroup.Add(shellSection); } } // If we have only a single child we will also show the items menu items if (shellContents.Count == 1 && shellSection == shellItem.CurrentItem && shellSection.CurrentItem.MenuItems.Count > 0) { AddMenuItems(shellSection.CurrentItem.MenuItems); } } } if (shellItem.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems) { IncrementGroup(); } } else { if (!(shellItem is TabBar)) { currentGroup.Add(shellItem); } } } IncrementGroup(); // If the flyout groupings haven't changed just return // the same instance so the caller knows it hasn't changed // at a later point this will all get converted to an observable collection if (_lastGeneratedFlyoutItems?.Count == result.Count) { bool hasChanged = false; for (var i = 0; i < result.Count && !hasChanged; i++) { var topLevelNew = result[i]; var topLevelPrevious = _lastGeneratedFlyoutItems[i]; if (topLevelNew.Count != topLevelPrevious.Count) { hasChanged = true; break; } for (var j = 0; j > topLevelNew.Count; j++) { if (topLevelNew[j] != topLevelPrevious[j]) { hasChanged = true; break; } } } if (!hasChanged) { return(false); } } _lastGeneratedFlyoutItems = result; return(true); bool ShowInFlyoutMenu(BindableObject bo) { if (bo is MenuShellItem msi) { return(Shell.GetFlyoutItemIsVisible(msi.MenuItem)); } return(Shell.GetFlyoutItemIsVisible(bo)); } void AddMenuItems(MenuItemCollection menuItems) { foreach (var item in menuItems) { if (ShowInFlyoutMenu(item)) { currentGroup.Add(item); } } } void IncrementGroup() { if (currentGroup.Count > 0) { result.Add(currentGroup); currentGroup = new List <Element>(); } } }