Skip to content
Merged
26 changes: 26 additions & 0 deletions src/Controls/src/Core/FlyoutPage/FlyoutPage.Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public partial class FlyoutPage
#if IOS
FlyoutViewHandler.Mapper.ReplaceMapping<IFlyoutView, IFlyoutViewHandler>(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty), MapPrefersHomeIndicatorAutoHiddenProperty);
FlyoutViewHandler.Mapper.ReplaceMapping<IFlyoutView, IFlyoutViewHandler>(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty), MapPrefersPrefersStatusBarHiddenProperty);
#endif
#if WINDOWS
FlyoutViewHandler.Mapper.ReplaceMapping<IFlyoutView, IFlyoutViewHandler>(nameof(PlatformConfiguration.WindowsSpecific.FlyoutPage.CollapseStyleProperty), MapCollapseStyle);
#endif
}

Expand All @@ -31,5 +34,28 @@ internal static void MapPrefersPrefersStatusBarHiddenProperty(IFlyoutViewHandler
handler.UpdateValue(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty));
}
#endif

#if WINDOWS
internal static void MapCollapseStyle(IFlyoutViewHandler handler, IFlyoutView view)
{
var flyoutLayoutBehavior = (view as FlyoutPage)?.FlyoutLayoutBehavior;
if (view is BindableObject bindable && handler.PlatformView is Microsoft.Maui.Platform.RootNavigationView navigationView && flyoutLayoutBehavior is FlyoutLayoutBehavior.Popover)
{
var collapseStyle = PlatformConfiguration.WindowsSpecific.FlyoutPage.GetCollapseStyle(bindable);
switch (collapseStyle)
{
case PlatformConfiguration.WindowsSpecific.CollapseStyle.Partial:
navigationView.FlyoutPaneDisplayMode = Microsoft.UI.Xaml.Controls.NavigationViewPaneDisplayMode.LeftCompact;
navigationView.PaneDisplayMode = Microsoft.UI.Xaml.Controls.NavigationViewPaneDisplayMode.LeftCompact;
break;
case PlatformConfiguration.WindowsSpecific.CollapseStyle.Full:
default:
navigationView.FlyoutPaneDisplayMode = null;
navigationView.PaneDisplayMode = Microsoft.UI.Xaml.Controls.NavigationViewPaneDisplayMode.LeftMinimal;
break;
}
}
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ public static class FlyoutPage
/// <summary>Bindable property for <see cref="CollapseStyle"/>.</summary>
public static readonly BindableProperty CollapseStyleProperty =
BindableProperty.CreateAttached("CollapseStyle", typeof(CollapseStyle),
typeof(FlyoutPage), CollapseStyle.Full);
typeof(FlyoutPage), CollapseStyle.Full, propertyChanged: OnCollapseStylePropertyChanged);

static void OnCollapseStylePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is Microsoft.Maui.Controls.FlyoutPage flyoutPage && flyoutPage.Handler is not null)
{
flyoutPage.Handler.UpdateValue(nameof(CollapseStyleProperty));
}
}

/// <include file="../../../../docs/Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific/FlyoutPage.xml" path="//Member[@MemberName='GetCollapseStyle'][1]/Docs/*" />
public static CollapseStyle GetCollapseStyle(BindableObject element)
Expand Down
79 changes: 79 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue18200.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Microsoft.Maui.Controls.PlatformConfiguration;
using Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific;
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra space in the using statement that creates inconsistent formatting with other using statements in the file.

Suggested change
using Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific;
using Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific;

Copilot uses AI. Check for mistakes.

namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 18200, "Flyout Page SetCollapseStyle doesn't have any change", PlatformAffected.UWP)]
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PlatformAffected.UWP value is outdated. MAUI uses Windows (WinUI3) instead of UWP (Universal Windows Platform). This should be PlatformAffected.Windows or simply PlatformAffected.All if testing on all platforms is acceptable.

Suggested change
[Issue(IssueTracker.Github, 18200, "Flyout Page SetCollapseStyle doesn't have any change", PlatformAffected.UWP)]
[Issue(IssueTracker.Github, 18200, "Flyout Page SetCollapseStyle doesn't have any change", PlatformAffected.Windows)]

Copilot uses AI. Check for mistakes.
public class Issue18200 : TestFlyoutPage
{
Button _button;
protected override void Init()
{
this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().SetCollapseStyle(CollapseStyle.Partial);

// Set the flyout page properties
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;

// Create the flyout content
var flyoutPage = new ContentPage
{
Title = "Master",
BackgroundColor = Colors.Blue
};

var page1Button = new Button
{
Text = "Page1",
AutomationId = "FlyoutItem",
HorizontalOptions = LayoutOptions.Start,
VerticalOptions = LayoutOptions.Center
};

flyoutPage.Content = new VerticalStackLayout
{
Children = { page1Button }
};

// Create the detail content
var detailPage = new ContentPage
{
Title = "Detail",
BackgroundColor = Colors.LightYellow
};

_button = new Button
{
Text = "Change Collapse Style",
AutomationId = "CollapseStyleButton",
};
_button.Clicked += OnCollapseStyleValueChanged;

detailPage.Content = new VerticalStackLayout
{
Children = {
new Microsoft.Maui.Controls.Label
{
Text = "Welcome to .NET MAUI!",
TextColor = Colors.Black,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
},
_button
}
};

// Set the flyout and detail pages
Flyout = flyoutPage;
Detail = detailPage;
}

void OnCollapseStyleValueChanged(object sender, EventArgs e)
{
var currentCollapseStyle = this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().GetCollapseStyle();
var newCollapseStyle = currentCollapseStyle == CollapseStyle.Full
? CollapseStyle.Partial
: CollapseStyle.Full;

this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().SetCollapseStyle(newCollapseStyle);
}
Comment on lines +11 to +78
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] According to the MAUI coding guidelines, file indentation should use tabs, but this file uses spaces for indentation (4 spaces). While this might be consistent within the immediate context, the repository standard is to use tabs. Consider running dotnet format to ensure consistent formatting.

Suggested change
{
this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().SetCollapseStyle(CollapseStyle.Partial);
// Set the flyout page properties
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
// Create the flyout content
var flyoutPage = new ContentPage
{
Title = "Master",
BackgroundColor = Colors.Blue
};
var page1Button = new Button
{
Text = "Page1",
AutomationId = "FlyoutItem",
HorizontalOptions = LayoutOptions.Start,
VerticalOptions = LayoutOptions.Center
};
flyoutPage.Content = new VerticalStackLayout
{
Children = { page1Button }
};
// Create the detail content
var detailPage = new ContentPage
{
Title = "Detail",
BackgroundColor = Colors.LightYellow
};
_button = new Button
{
Text = "Change Collapse Style",
AutomationId = "CollapseStyleButton",
};
_button.Clicked += OnCollapseStyleValueChanged;
detailPage.Content = new VerticalStackLayout
{
Children = {
new Microsoft.Maui.Controls.Label
{
Text = "Welcome to .NET MAUI!",
TextColor = Colors.Black,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
},
_button
}
};
// Set the flyout and detail pages
Flyout = flyoutPage;
Detail = detailPage;
}
void OnCollapseStyleValueChanged(object sender, EventArgs e)
{
var currentCollapseStyle = this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().GetCollapseStyle();
var newCollapseStyle = currentCollapseStyle == CollapseStyle.Full
? CollapseStyle.Partial
: CollapseStyle.Full;
this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().SetCollapseStyle(newCollapseStyle);
}
{
this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().SetCollapseStyle(CollapseStyle.Partial);
// Set the flyout page properties
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
// Create the flyout content
var flyoutPage = new ContentPage
{
Title = "Master",
BackgroundColor = Colors.Blue
};
var page1Button = new Button
{
Text = "Page1",
AutomationId = "FlyoutItem",
HorizontalOptions = LayoutOptions.Start,
VerticalOptions = LayoutOptions.Center
};
flyoutPage.Content = new VerticalStackLayout
{
Children = { page1Button }
};
// Create the detail content
var detailPage = new ContentPage
{
Title = "Detail",
BackgroundColor = Colors.LightYellow
};
_button = new Button
{
Text = "Change Collapse Style",
AutomationId = "CollapseStyleButton",
};
_button.Clicked += OnCollapseStyleValueChanged;
detailPage.Content = new VerticalStackLayout
{
Children = {
new Microsoft.Maui.Controls.Label
{
Text = "Welcome to .NET MAUI!",
TextColor = Colors.Black,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
},
_button
}
};
// Set the flyout and detail pages
Flyout = flyoutPage;
Detail = detailPage;
}
void OnCollapseStyleValueChanged(object sender, EventArgs e)
{
var currentCollapseStyle = this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().GetCollapseStyle();
var newCollapseStyle = currentCollapseStyle == CollapseStyle.Full
? CollapseStyle.Partial
: CollapseStyle.Full;
this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>().SetCollapseStyle(newCollapseStyle);
}

Copilot uses AI. Check for mistakes.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# if WINDOWS // It's a Windows specific API issue, so restricting the other platforms
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue18200 : _IssuesUITest
{
public Issue18200(TestDevice device)
: base(device)
{ }

public override string Issue => "Flyout Page SetCollapseStyle doesn't have any change";

[Test]
[Category(UITestCategories.FlyoutPage)]
public void VerifyFlyoutCollapseStyleBehaviorChanges()
{
App.WaitForElement("CollapseStyleButton");
App.Tap("CollapseStyleButton");
App.TapFlyoutPageIcon();
App.TapFlyoutPageIcon(); // Close the flyout
App.WaitForNoElement("FlyoutItem");
App.Tap("CollapseStyleButton");
App.WaitForElement("FlyoutItem");
}
}
#endif
10 changes: 8 additions & 2 deletions src/Core/src/Platform/Windows/MauiNavigationView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,14 @@ internal void UpdatePaneDisplayModeFromFlyoutBehavior(FlyoutBehavior flyoutBehav
{
case FlyoutBehavior.Flyout:
IsPaneToggleButtonVisible = true;
var flyoutMode = FlyoutPaneDisplayMode ?? NavigationViewPaneDisplayMode.LeftMinimal;
// WinUI bug: Setting PaneDisplayMode to the same value and updating SelectedItem during navigation
// causes the selection and selected item indicator to not update correctly.
// Workaround: Only set PaneDisplayMode when the value actually changes.
// Related: https://github.com/microsoft/microsoft-ui-xaml/issues/9812
if (PaneDisplayMode != NavigationViewPaneDisplayMode.LeftMinimal)
if (PaneDisplayMode != flyoutMode)
{
PaneDisplayMode = NavigationViewPaneDisplayMode.LeftMinimal;
PaneDisplayMode = flyoutMode;
}
break;
case FlyoutBehavior.Locked:
Expand Down Expand Up @@ -371,6 +372,11 @@ internal static readonly DependencyProperty PaneToggleButtonWidthProperty
new PropertyMetadata(DefaultPaneToggleButtonWidth, OnPaneToggleButtonSizeChanged));
private NavigationViewPaneDisplayMode? _pinPaneDisplayModeTo;

// Stores the preferred pane display mode for FlyoutBehavior.Flyout, set by CollapseStyle on Windows.
// When null, the default LeftMinimal is used. This ensures CollapseStyle.Partial (LeftCompact) survives
// layout-driven FlyoutBehavior re-evaluations (e.g. size/orientation changes).
internal NavigationViewPaneDisplayMode? FlyoutPaneDisplayMode { get; set; }

internal double PaneToggleButtonWidth
{
get => (double)GetValue(PaneToggleButtonWidthProperty);
Expand Down
Loading