You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WinUI 3中实现局部区域显示的欢迎导航屏幕

解决WinUI 3局部区域页面导航的问题

问题概述

我正在用WinUI 3开发欢迎屏幕,需求如下:

  • 点击返回、下一步按钮,可在3个页面间导航;
  • 页面内容仅显示在主窗口水平线以上的区域;
  • 通过三个圆点标识总页数和当前页面。

官方导航示例是用整个窗口做导航,我需要修改成仅在指定局部区域显示导航页面,现有代码如下:

现有代码

MainWindow.xaml

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="BasicNavigation.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BasicNavigation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
>

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"
    >
   
    </StackPanel>
</Window>

App.xaml.cs

protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    m_window = new MainWindow();

    // Create a Frame to act as the navigation context and navigate to the first page
    Frame rootFrame = new Frame();
    rootFrame.NavigationFailed += OnNavigationFailed;
    // Navigate to the first page, configuring the new page
    // by passing required information as a navigation parameter
    rootFrame.Navigate(typeof(MainPage), args.Arguments);

    // Place the frame in the current Window
    m_window.Content = rootFrame;
    // Ensure the MainWindow is active
    m_window.Activate();
}

void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
    throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}

解决方案

核心思路是不要把Frame设为窗口的整个Content,而是将Frame嵌入到MainWindow的指定布局区域内,同时保留导航逻辑。以下是具体修改步骤:

1. 修改MainWindow.xaml,规划局部导航区域

在窗口中划分出导航内容区、控制按钮区和页码指示器,示例布局如下:

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="BasicNavigation.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BasicNavigation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Width="800" Height="600"
>
    <Grid>
        <!-- 水平线以上的导航内容区 -->
        <Frame x:Name="NavigationFrame" Margin="20" Height="350" VerticalAlignment="Top"/>
        
        <!-- 分隔线 -->
        <Rectangle Fill="Gray" Height="1" VerticalAlignment="Center"/>
        
        <!-- 底部控制区:返回/下一步按钮 + 页码圆点 -->
        <StackPanel Orientation="Vertical" VerticalAlignment="Bottom" Margin="0 20 0 20">
            <!-- 按钮栏 -->
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="20">
                <Button x:Name="BackButton" Content="返回" Click="BackButton_Click" IsEnabled="False"/>
                <Button x:Name="NextButton" Content="下一步" Click="NextButton_Click"/>
            </StackPanel>
            
            <!-- 页码指示器 -->
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0 15 0 0" Spacing="8">
                <Ellipse x:Name="Dot1" Fill="Blue" Width="12" Height="12"/>
                <Ellipse x:Name="Dot2" Fill="LightGray" Width="12" Height="12"/>
                <Ellipse x:Name="Dot3" Fill="LightGray" Width="12" Height="12"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

2. 修改App.xaml.cs,初始化局部Frame

不再把Frame设为窗口Content,而是直接在MainWindow加载时初始化内部的NavigationFrame:

protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    m_window = new MainWindow();
    
    // 获取窗口内的导航Frame
    Frame navFrame = (m_window as MainWindow).NavigationFrame;
    navFrame.NavigationFailed += OnNavigationFailed;
    // 导航到第一个页面
    navFrame.Navigate(typeof(WelcomePage1), args.Arguments);
    
    m_window.Activate();
}

void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
    throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}

3. 实现导航逻辑和页码更新

在MainWindow.xaml.cs中添加按钮点击事件和导航状态监听:

using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;

namespace BasicNavigation
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            // 监听导航事件,更新按钮状态和页码圆点
            NavigationFrame.Navigated += NavigationFrame_Navigated;
        }

        private void BackButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
        {
            if (NavigationFrame.CanGoBack)
            {
                NavigationFrame.GoBack();
            }
        }

        private void NextButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
        {
            // 根据当前页面判断下一步导航目标
            if (NavigationFrame.Content is WelcomePage1)
            {
                NavigationFrame.Navigate(typeof(WelcomePage2));
            }
            else if (NavigationFrame.Content is WelcomePage2)
            {
                NavigationFrame.Navigate(typeof(WelcomePage3));
            }
            // 如果是最后一页,可以添加完成逻辑
        }

        private void NavigationFrame_Navigated(object sender, NavigationEventArgs e)
        {
            // 更新返回按钮状态
            BackButton.IsEnabled = NavigationFrame.CanGoBack;
            
            // 更新页码圆点
            Dot1.Fill = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.LightGray);
            Dot2.Fill = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.LightGray);
            Dot3.Fill = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.LightGray);
            
            if (e.SourcePageType == typeof(WelcomePage1))
            {
                Dot1.Fill = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Blue);
                NextButton.Content = "下一步";
            }
            else if (e.SourcePageType == typeof(WelcomePage2))
            {
                Dot2.Fill = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Blue);
                NextButton.Content = "下一步";
            }
            else if (e.SourcePageType == typeof(WelcomePage3))
            {
                Dot3.Fill = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Blue);
                NextButton.Content = "完成";
            }
        }
    }
}

4. 创建欢迎页面(示例)

分别创建WelcomePage1.xaml、WelcomePage2.xaml、WelcomePage3.xaml,每个页面只需添加简单内容即可,比如:

<!-- WelcomePage1.xaml -->
<Page
    x:Class="BasicNavigation.WelcomePage1"
    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"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock Text="欢迎页面1" FontSize="24"/>
    </StackPanel>
</Page>

关键说明

  • 导航Frame是嵌入在MainWindow的Grid布局中的,仅占据顶部指定区域,不会覆盖整个窗口;
  • 通过监听Frame的Navigated事件,实时更新返回按钮状态和页码指示器的圆点颜色;
  • 下一步按钮的逻辑可以根据实际需求调整,比如最后一页改为"完成"并执行结束流程。

内容的提问来源于stack exchange,提问作者Ming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:04:59