如何在UWP NavigationView控件PaneDisplayMode设为Top时居中导航项?
当PaneDisplayMode设置为Top时,直接设置NavigationView的HorizontalContentAlignment无法让导航项居中,原因是导航项的容器(默认名为TopPaneMenuItemsHost的StackPanel)默认左对齐,且该容器的对齐属性不会继承自NavigationView本身。下面提供两种可行的实现方式:
方法一:修改NavigationView模板(推荐)
通过自定义NavigationView的控件模板,调整顶部导航项容器的对齐方式,这种方式稳定性更高,不依赖额外代码逻辑:
<Page.Resources> <Style TargetType="NavigationView"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="NavigationView"> <Grid x:Name="RootGrid"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!-- 顶部面板区域 --> <Grid x:Name="TopPaneGrid" Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <!-- 返回按钮 --> <NavigationViewBackButton x:Name="BackButton" Grid.Column="0" Visibility="{TemplateBinding IsBackButtonVisible}" Margin="12,0"/> <!-- 导航项容器:修改HorizontalAlignment为Center实现居中 --> <StackPanel x:Name="TopPaneMenuItemsHost" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center" IsItemsHost="True" Margin="0,12"/> <!-- 面板切换按钮 --> <Button x:Name="PaneToggleButton" Grid.Column="2" Visibility="{TemplateBinding IsPaneToggleButtonVisible}" Style="{StaticResource PaneToggleButtonStyle}" Margin="12,0"/> </Grid> <!-- 内容区域 --> <ContentPresenter x:Name="ContentPresenter" Grid.Row="1" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Page.Resources> <Grid> <NavigationView PaneDisplayMode="Top"> <NavigationView.MenuItems> <NavigationViewItem Content="导航项1"/> <NavigationViewItem Content="导航项2"/> <NavigationViewItem Content="导航项3"/> </NavigationView.MenuItems> </NavigationView> </Grid>
方法二:通过代码后台修改内部容器属性
如果不想修改完整模板,可以在页面加载时通过视觉树查找顶部导航项容器,修改其对齐属性:
XAML部分
<Grid> <NavigationView x:Name="MyNavView" PaneDisplayMode="Top" Loaded="MyNavView_Loaded"> <NavigationView.MenuItems> <NavigationViewItem Content="导航项1"/> <NavigationViewItem Content="导航项2"/> <NavigationViewItem Content="导航项3"/> </NavigationView.MenuItems> </NavigationView> </Grid>
C#后台代码
private void MyNavView_Loaded(object sender, RoutedEventArgs e) { var topMenuContainer = FindVisualChild<StackPanel>(MyNavView, "TopPaneMenuItemsHost"); if (topMenuContainer != null) { // 设置容器居中对齐 topMenuContainer.HorizontalAlignment = HorizontalAlignment.Center; // 若需要导航项在容器内均匀分布,可改为以下设置: // topMenuContainer.HorizontalAlignment = HorizontalAlignment.Stretch; // topMenuContainer.HorizontalContentAlignment = HorizontalAlignment.Center; } } // 视觉树查找辅助方法 private T FindVisualChild<T>(DependencyObject parent, string controlName) where T : FrameworkElement { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); if (child is T targetElement && targetElement.Name == controlName) { return targetElement; } var result = FindVisualChild<T>(child, controlName); if (result != null) { return result; } } return null; }
注意:方法二依赖UWP内部控件的命名(
TopPaneMenuItemsHost),若微软后续更新控件模板修改该名称,此方法会失效,因此更推荐使用方法一。
内容的提问来源于stack exchange,提问作者Light
相关产品推荐
相关产品推荐

