UWP开发笔记——嵌套式页面的实现
绪论
UWP开发中,Page是最常用的Control之一,通常情况下,在开发的application中,每一个页面就是一个Page。有时候,为了开发整合度更高,UI表现更为一致的UI,开发者需要把UI控件和功能整合到一个页面的子页面中,子页面拥有自己的UI表现和生命周期,这就需要在Page中嵌套Page来达到需要实现的效果。
一种实现方法
其实,实现嵌套页面是一件很简单的事情,我们知道,page都是通过Frame显示和控制Navigation的,基于这点,就可以在主页面(即最外层的页面)中添加一个Frame,通过控制这个Frame来实现子Page的显示和导航。
在xmal中添加Frame
<Frame x:Name="contentFrame" Grid.Row="1"/>
在code中实现子Page的navigation
contentFrame.Navigate(typeof(Page1));
为子Frame添加默认的Page
protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { contentFrame.Navigate(typeof(Page1)); } base.OnNavigatedTo(e); }
为back键添加Event
public MainPage() { this.InitializeComponent(); SystemNavigationManager.GetForCurrentView().BackRequested += PageBackRequested; } private void PageBackRequested(object sender, BackRequestedEventArgs e) { if (contentFrame == null) return; if (contentFrame.CanGoBack) { e.Handled = true; contentFrame.GoBack(); } }
一个例子
在这个例子中,外层的MainPage有一个汉堡键配合SplitView菜单实现内层Page的切换,back键用来实现contentFrame的Navigation。其中,Page1和Page2是嵌套在MainPage里面的两个Page。
MainPage.xaml
<Page x:Class="NestedFrameExample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:NestedFrameExample" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid Height="48" VerticalAlignment="Top" Background="White"> <Button x:Name="hamburgerButton" Background="Transparent" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Click="SplitViewToggle_Click"> <TextBlock Text="" FontFamily="{ThemeResource SymbolThemeFontFamily}"/> </Button> </Grid> <!-- 这个Frame用于显示子Page页面。 --> <Frame x:Name="contentFrame" Grid.Row="1"/> <SplitView x:Name="splitView" Grid.Row="1" IsPaneOpen="False" OpenPaneLength="300" CompactPaneLength="48" DisplayMode="Overlay" HorizontalContentAlignment="Stretch"> <SplitView.Pane> <ListView ItemsSource="{x:Bind Path=NavLinks}" IsItemClickEnabled="True" ItemClick="NavLinkClick" SelectionMode="None"/> </SplitView.Pane> </SplitView> </Grid> </Page>
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Core; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace NestedFrameExample { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public List<NavLink> NavLinks = new List<NavLink>() { new NavLink() { Label = "Page1", LinkType = typeof(Page1) }, new NavLink() { Label = "Page2", LinkType = typeof(Page2) } }; public MainPage() { this.InitializeComponent(); SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible; SystemNavigationManager.GetForCurrentView().BackRequested += PageBackRequested; } private void NavLinkClick(object sender, ItemClickEventArgs e) { NavLink link = e.ClickedItem as NavLink; if (link != null && link.LinkType != null) contentFrame.Navigate(link.LinkType); splitView.IsPaneOpen = false; } private void SplitViewToggle_Click(object sender, RoutedEventArgs e) { splitView.IsPaneOpen = !splitView.IsPaneOpen; } protected override void OnNavigatedTo(NavigationEventArgs e) { //this.InitialBackButton(); if (e.NavigationMode == NavigationMode.New) { contentFrame.Navigate(typeof(Page1)); } base.OnNavigatedTo(e); } private void PageBackRequested(object sender, BackRequestedEventArgs e) { if (contentFrame == null) return; if (contentFrame.CanGoBack) { e.Handled = true; contentFrame.GoBack(); } } } public class NavLink { public String Label { get; set; } public Type LinkType { get; set; } public override String ToString() { return Label; } } }
总结
嵌套式的页面使每个Page的结构更加清晰,更能专注于自己的功能实现,也使代码更加清晰,容易维护,避免代码冗余,推荐使用,希望本文能给大家带来帮助!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)