Skip to content

Commit 37f4a9c

Browse files
RedthCopilot
andcommitted
Redesign as a single result-oriented ResolveFlyoutItemTemplate API
Replaces the three algorithm-piece methods with one nullable-annotated, result-oriented entry point: public static DataTemplate? ResolveFlyoutItemTemplate(Shell? shell, BindableObject flyoutItem) It returns the final application-defined template, or null meaning "use your own platform-native default". Rationale for the change: * `Get*` on Shell reads as an attached-property accessor, which these were not. * Exposing the property/source/is-set trio froze the internal lookup levels as public contract. * The documented binding context was wrong. The built-in Android, iOS, and Windows backends all bind created content to the flyout item itself (`View.BindingContext = context` / `_content.BindingContext = bo`), not to the object that carried the template, which for `ShellContent.MenuItems` is the parent `ShellContent`. `MenuShellItem` and the paired-object lookup stay internal. Null handling is explicit: an item that sets the template property wins even when the value is null (so an app can opt one item out of a Shell level template), and a null or null-bound value is reported as "no template" rather than producing a true/null mismatch or an NRE in platform code. `IShellController.GetFlyoutItemDataTemplate` now composes the new method with the default flyout cell, so the in-box path never hands null to platform code. The Windows backend is dogfooded through the public API, and the in-box Tizen adaptor now resolves and null-checks in one step. Tests grow to 23 and add binding coverage: Text/Command bound through `ShellContent.MenuItems` and through Shell-level `MenuItemTemplate`, flyout selection invoking the command, item vs Shell template precedence, explicit null, null-bound, `DataTemplateSelector`, headers/footers and their templates, Shell resolution when the argument is omitted, unparented items, and argument validation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 7d740bf commit 37f4a9c

12 files changed

Lines changed: 343 additions & 204 deletions

File tree

src/Controls/src/Core/Handlers/Shell/Tizen/ShellFlyoutItemAdaptor.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,15 @@ public FlyoutItemDataTemplateSelector()
4949

5050
protected override DataTemplate? OnSelectTemplate(object item, BindableObject container)
5151
{
52-
DataTemplate template = DefaultItemTemplate;
53-
54-
if (item != null && item is BindableObject bo)
52+
if (item is BindableObject bo)
5553
{
56-
if (Shell.IsFlyoutItemTemplateSet(container as Shell, bo))
57-
{
58-
DataTemplate? dataTemplate = (container as IShellController)?.GetFlyoutItemDataTemplate(bo);
59-
template = dataTemplate.SelectDataTemplate(item, container);
60-
}
54+
var dataTemplate = Shell.ResolveFlyoutItemTemplate(container as Shell, bo);
55+
56+
if (dataTemplate is not null)
57+
return dataTemplate.SelectDataTemplate(item, container);
6158
}
62-
return template;
59+
60+
return DefaultItemTemplate;
6361
}
6462
}
6563
}

src/Controls/src/Core/Handlers/Shell/Windows/ShellFlyoutItemView.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ void OnDataContextChanged(Microsoft.UI.Xaml.FrameworkElement sender, Microsoft.U
6666

6767
var element = bo as Element;
6868
_shell = element?.FindParentOfType<Shell>();
69-
DataTemplate dataTemplate = (_shell as IShellController)?.GetFlyoutItemDataTemplate(bo);
69+
70+
// Resolve the application supplied template through the same public contract external backends use.
71+
// A null result means the application did not supply one, so fall back to the default flyout item cell.
72+
DataTemplate dataTemplate = null;
73+
74+
if (bo != null && _shell != null)
75+
dataTemplate = Shell.ResolveFlyoutItemTemplate(_shell, bo) ?? BaseShellItem.CreateDefaultFlyoutItemCell(bo);
7076

7177
if (bo != null)
7278
bo.PropertyChanged += ShellElementPropertyChanged;

src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,4 @@ virtual Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutTemplatedConte
319319
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
320320
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
321321
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
322-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
323-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
324-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
322+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,4 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
239239
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
240240
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
241241
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
242-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
243-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
244-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
242+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,4 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
231231
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
232232
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
233233
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
234-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
235-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
236-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
234+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,4 @@ Microsoft.Maui.Controls.Label.~Label() -> void
223223
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
224224
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
225225
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
226-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
227-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
228-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
226+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,4 @@ static Microsoft.Maui.Controls.Platform.FormattedStringExtensions.ToRunAndColors
274274
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
275275
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
276276
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
277-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
278-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
279-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
277+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,4 @@ Microsoft.Maui.Controls.Label.~Label() -> void
218218
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
219219
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
220220
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
221-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
222-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
223-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
221+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,4 @@ Microsoft.Maui.Controls.Label.~Label() -> void
209209
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeColorProperty -> Microsoft.Maui.Controls.BindableProperty
210210
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextColorProperty -> Microsoft.Maui.Controls.BindableProperty
211211
~static readonly Microsoft.Maui.Controls.TabbedPage.BadgeTextProperty -> Microsoft.Maui.Controls.BindableProperty
212-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateProperty(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableProperty
213-
~static Microsoft.Maui.Controls.Shell.GetFlyoutItemTemplateSource(Microsoft.Maui.Controls.BindableObject flyoutItem) -> Microsoft.Maui.Controls.BindableObject
214-
~static Microsoft.Maui.Controls.Shell.IsFlyoutItemTemplateSet(Microsoft.Maui.Controls.Shell shell, Microsoft.Maui.Controls.BindableObject flyoutItem) -> bool
212+
static Microsoft.Maui.Controls.Shell.ResolveFlyoutItemTemplate(Microsoft.Maui.Controls.Shell? shell, Microsoft.Maui.Controls.BindableObject! flyoutItem) -> Microsoft.Maui.Controls.DataTemplate?

src/Controls/src/Core/Shell/BaseShellItem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ internal static DataTemplate CreateDefaultFlyoutItemCell(BindableObject bo)
615615
if (sender is Grid g)
616616
{
617617
var bo = g.BindingContext as BindableObject;
618-
var styleClassSource = (bo is null ? null : Shell.GetFlyoutItemTemplateSource(bo)) as IStyleSelectable;
618+
var styleClassSource = (bo is null ? null : Shell.GetBindableObjectWithFlyoutItemTemplate(bo)) as IStyleSelectable;
619619
UpdateFlyoutItemStyles(g, styleClassSource);
620620

621621
// this means they haven't changed the BaseShellItemContext so we are

0 commit comments

Comments
 (0)