如何配置随菜单开闭伸缩的全局可见Horizontal StackPanel?
要让全局头部始终可见且随菜单伸缩,关键是让头部与NavigationView的面板宽度联动,而非独立于NavigationView布局。以下是修改后的实现方案:
修改后的完整XAML代码
<Page x:Class="Application.Views.ShellPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:helpers="using:Application.Helpers" xmlns:behaviors="using:Application.Behaviors" xmlns:i="using:Microsoft.Xaml.Interactivity" Loaded="OnLoaded"> <Grid> <!-- 保留原窗口标题栏 --> <Grid x:Name="AppTitleBar" Canvas.ZIndex="1" Height="{Binding ElementName=NavigationViewControl, Path=CompactPaneLength}" IsHitTestVisible="True" VerticalAlignment="Top"> <Image Source="/Assets/WindowIcon.ico" HorizontalAlignment="Left" Width="16" Height="16" /> <TextBlock x:Name="AppTitleBarText" VerticalAlignment="Center" TextWrapping="NoWrap" Style="{StaticResource CaptionTextBlockStyle}" Margin="28,0,0,0"/> </Grid> <NavigationView x:Name="NavigationViewControl" Canvas.ZIndex="0" IsBackButtonVisible="Visible" IsBackEnabled="{x:Bind ViewModel.IsBackEnabled, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}" IsSettingsVisible="True" ExpandedModeThresholdWidth="1280" DisplayModeChanged="NavigationViewControl_DisplayModeChanged" Header="{x:Bind ((ContentControl)ViewModel.Selected).Content, Mode=OneWay}"> <NavigationView.MenuItems> <!-- 保留原菜单内容 --> </NavigationView.MenuItems> <NavigationView.HeaderTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding}" Style="{ThemeResource TitleTextBlockStyle}" /> </Grid> </DataTemplate> </NavigationView.HeaderTemplate> <i:Interaction.Behaviors> <behaviors:NavigationViewHeaderBehavior DefaultHeader="{x:Bind ((ContentControl)ViewModel.Selected).Content, Mode=OneWay}"> <behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding}" Style="{ThemeResource TitleTextBlockStyle}" /> </Grid> </DataTemplate> </behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate> </behaviors:NavigationViewHeaderBehavior> </i:Interaction.Behaviors> <!-- 重新布局Content区域:先放全局头部,再放页面Frame --> <StackPanel Orientation="Vertical"> <!-- 全局统一头部StackPanel --> <StackPanel x:Name="GlobalHeader" Orientation="Horizontal" Background="{ThemeResource SystemControlAcrylicWindowBrush}" Height="60" VerticalAlignment="Top" Padding="16,0"> <!-- 头部内容示例:可替换为你的自定义控件 --> <TextBlock Text="全局统一头部" Style="{ThemeResource TitleTextBlockStyle}" VerticalAlignment="Center"/> <Button Content="功能按钮" Margin="24,0" VerticalAlignment="Center"/> </StackPanel> <!-- 页面内容区域 --> <Grid Margin="{StaticResource NavigationViewPageContentMargin}" VerticalAlignment="Stretch"> <Frame x:Name="NavigationFrame" /> </Grid> </StackPanel> </NavigationView> </Grid> </Page>
关键实现细节
- 布局嵌套:将全局头部放在NavigationView的Content内部,与页面Frame处于同一垂直StackPanel中,确保头部始终在页面内容上方,切换页面时不会消失。
- 菜单联动逻辑:在
NavigationViewControl_DisplayModeChanged事件中手动设置头部的左边距,适配菜单展开/收起状态:
private void NavigationViewControl_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args) { // 根据菜单显示模式设置头部左边距 double leftPadding = sender.DisplayMode switch { NavigationViewDisplayMode.Expanded => sender.ExpandedPaneLength, NavigationViewDisplayMode.Minimal => 0, _ => sender.CompactPaneLength }; GlobalHeader.Margin = new Thickness(leftPadding, 0, 0, 0); }
- 样式适配:头部使用
SystemControlAcrylicWindowBrush背景,保持与WinUI风格一致,高度和内边距可根据需求调整。
替代方案(使用绑定转换器)
如果不想通过事件处理,可自定义DoubleToThicknessConverter,直接绑定PaneActualWidth属性到头部的左边距:
public class DoubleToThicknessConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { double width = (double)value; return new Thickness(width, 0, 0, 0); } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } }
在XAML中引用转换器后,头部的Margin可改为:
Margin="{Binding ElementName=NavigationViewControl, Path=PaneActualWidth, Converter={StaticResource DoubleToThicknessConverter}}"
内容的提问来源于stack exchange,提问作者mainhar2
相关产品推荐
相关产品推荐

