.NET WinUI3应用添加过多MenuFlyoutItem时MenuItem不显示
这是WinUI3的已知布局渲染问题:当MenuFlyout包含的菜单项总高度超过当前窗口高度时,初始化阶段无法正确计算布局导致菜单显示为空,调整窗口尺寸后布局重新计算才会正常显示(带滚动效果)。以下是几个可行的解决方案:
方案1:延迟加载菜单项到第一次点击时
将菜单项的添加逻辑从初始化阶段移到菜单第一次被点击时执行,确保布局计算基于当前窗口尺寸:
private bool _menuItemsLoaded = false; private void CollectionMenu_Tapped(object sender, TappedRoutedEventArgs e) { if (!_menuItemsLoaded) { foreach (string c in CollectionNames) { var item = new MenuFlyoutItem { Name = c, Text = c }; item.Click += CollectionNameMenuClick; CollectionMenu.Items.Add(item); } _menuItemsLoaded = true; } }
方案2:显式设置MenuFlyout的最大高度
为目标MenuBarItem指定自定义MenuFlyout,并动态设置其最大高度为窗口可用高度的合理值,避免内容超出窗口范围:
XAML 修改:
<MenuBarItem x:Name="CollectionMenu" Title="Collection" Tapped="CollectionMenu_Tapped"> <MenuBarItem.Flyout> <MenuFlyout x:Name="CollectionFlyout" MaxHeight="{x:Bind GetMenuMaxHeight(), Mode=OneWay}"/> </MenuBarItem.Flyout> </MenuBarItem>
C# 后台代码:
private double GetMenuMaxHeight() { // 计算窗口可用高度,减去菜单栏高度和边距 var appWindow = AppWindow.GetForCurrentView(); double windowHeight = appWindow.ClientSize.Height; double menuBarHeight = MenuBar.ActualHeight; return windowHeight - menuBarHeight - 10; } // 初始化时将菜单项添加到自定义Flyout foreach (string c in CollectionNames) { var item = new MenuFlyoutItem { Name = c, Text = c }; item.Click += CollectionNameMenuClick; CollectionFlyout.Items.Add(item); }
方案3:使用自定义Flyout替代默认MenuFlyout
通过ScrollViewer+StackPanel构建自定义Flyout,完全控制滚动逻辑,彻底规避WinUI3的原生布局Bug:
XAML 修改:
<MenuBarItem x:Name="CollectionMenu" Title="Collection"> <MenuBarItem.Flyout> <Flyout> <ScrollViewer MaxHeight="400" VerticalScrollBarVisibility="Auto"> <StackPanel x:Name="CustomCollectionMenuItems"/> </ScrollViewer> </Flyout> </MenuBarItem.Flyout> </MenuBarItem>
C# 后台代码:
foreach (string c in CollectionNames) { var item = new MenuFlyoutItem { Name = c, Text = c }; item.Click += CollectionNameMenuClick; CustomCollectionMenuItems.Children.Add(item); }
以上方案均可解决问题,其中方案1实现最简单,方案3灵活性最高,可根据实际需求选择。
内容的提问来源于stack exchange,提问作者Andy Runyon
相关产品推荐
相关产品推荐

