Skip to content
Shiny Controls v1.0 - The Ultra Control Suite for .NET MAUI & BlazorO...M...G!

Items & Overflow

Items are declared on the page, not on the navigation page — the same shape Page.ToolbarItems already has, so a page can be moved between hosts without any of it changing.

<ContentPage xmlns:shiny="http://shiny.net/maui/controls" Title="Inbox">
<shiny:ShinyNav.LeftItems>
<shiny:NavBarItem Icon="menu" Command="{Binding OpenDrawerCommand}" />
</shiny:ShinyNav.LeftItems>
<shiny:ShinyNav.RightItems>
<shiny:NavBarItem Icon="search" Command="{Binding SearchCommand}" />
<shiny:NavBarItem Icon="bell" Badge="3" Command="{Binding AlertsCommand}" />
<shiny:NavBarItem Text="Mark all read" Icon="check" Order="Secondary" Command="{Binding MarkAllCommand}" />
<shiny:NavBarItem IsSeparator="True" Order="Secondary" />
<shiny:NavBarItem Text="Delete all" Icon="trash" Order="Secondary" IsDestructive="True" Command="{Binding DeleteCommand}" />
</shiny:ShinyNav.RightItems>
</ContentPage>

It derives from ToolbarItem, so everything you already know keeps its meaning:

Inherited Meaning
Text the label
IconImageSource a bitmap or font glyph
Command / CommandParameter run on tap
Clicked raised on tap, after the command
IsEnabled a disabled item is dimmed and untappable
IsDestructive drawn in the theme’s error colour
Order Default/Primary on the bar, Secondary in the overflow menu
Priority orders items within their side

And it adds:

Added Meaning
Icon a built-in motion icon name — search, bell, trash
IconSource / IconPathData / Motion explicit motion artwork, a raw 24×24 SVG path, and which motion it plays
IconColor tints this item’s motion artwork
Badge / BadgeColor a corner badge — "" is a dot, null is nothing
Display Auto (icon when there is one), Icon, Text, IconAndText
IsVisible hides the item without removing it from the collection
IsSeparator a divider — in the menu only
Tag whatever identifies the item to your handler; Text is not unique

Because both collections are typed IList<ToolbarItem>, a plain <ToolbarItem> drops into either one unchanged.

Two rules, in this order:

  1. Order="Secondary" folds an item into that side’s overflow menu, however much room the bar has.
  2. Anything past MaxVisibleItems (default 3, per side) folds in behind it.

Set MaxVisibleItems="0" (or any value ≤ 0) for no limit, and then only Secondary items overflow. Each side gets its own overflow button, and a side with nothing to overflow gets none.

OverflowIcon names a motion icon to draw instead of the default three-dot glyph. MenuTemplate replaces the card’s contents wholesale while the bar keeps the backdrop, the anchoring and the open/close animation; its binding context is the collection that overflowed.

Open a menu yourself:

ShinyNavigationPage.GetNavBar(page)?.OpenMenu(NavBarSide.Right);

An attached-property collection has no parent, so nothing would ordinarily hand its items a binding context and every {Binding} on one would silently resolve against null. ShinyNavigationPage seeds the page’s binding context onto them as an inherited context, so bindings work and an explicit BindingContext on an item still wins.

Item properties are bindable, so nothing about the collection has to change for the bar to redraw:

// the bar rebuilds itself off the item's own PropertyChanged
alertsItem.Badge = unread == 0 ? null : unread.ToString();

Three ways, all live at once:

item.Command = new Command(...); // on the item
item.Clicked += (s, e) => { ... }; // on the item
nav.NavBarItemInvoked += (s, e) => { ... }; // on the navigation page, for any of its bars
bar.ItemInvoked += (s, e) => { ... }; // on one bar

The bar invokes an item through IMenuItemController.Activate() — the same call a native toolbar makes — so an item behaves identically whether it was drawn here or by the platform.