WinUI3中NavigationView激活但contentFrame显示黑屏的问题排查
问题现象
将NavigationView设置为顶部布局,完成面板配置并设置加载时默认导航至Home标签页,但contentFrame始终显示黑屏,无任何内容渲染。
代码片段
MainWindow.xaml
<Window x:Class="Ankara_Online.MainWindow" 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:local="using:Ankara_Online" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Orientation="Vertical"> <NavigationView x:Name="_navigationView" AlwaysShowHeader="False" ExpandedModeThresholdWidth="500" Header="Header" IsBackButtonVisible="Collapsed" IsBackEnabled="False" IsSettingsVisible="False" IsTabStop="False" ItemInvoked="NavigationView_ItemInvoked" Loaded="NavigationView_Loaded" PaneDisplayMode="Top" PaneTitle="navigationPane" SelectionFollowsFocus="Enabled"> <NavigationView.Resources> <SolidColorBrush x:Key="NavigationViewTopPaneBackground" Color="#195caa" /> </NavigationView.Resources> <NavigationView.PaneHeader> <Image Height="40" Margin="10,0,10,0" Style="{ThemeResource HeaderLogo}" /> </NavigationView.PaneHeader> <NavigationView.MenuItems> <NavigationViewItem x:Name="homeViewItem" Content="Home" FontFamily="Poppins" FontSize="16" FontWeight="Normal" Tag="homePageView"> <NavigationViewItem.Icon> <ImageIcon Source="./Assets/Icons/control-tower.png" /> </NavigationViewItem.Icon> </NavigationViewItem> <NavigationViewItemSeparator /> <NavigationViewItem x:Name="softwareSectorFileViewItem" Content="Applications and Sector Files" FontFamily="Poppins" FontSize="16" FontWeight="Normal" Tag="softwareSectorFileView"> <NavigationViewItem.Icon> <ImageIcon Source="./Assets/Icons/application.png" /> </NavigationViewItem.Icon> </NavigationViewItem> <NavigationViewItemSeparator /> <NavigationViewItem x:Name="DocumentsViewItem" Content="Documents" FontFamily="Poppins" FontSize="16" FontWeight="Normal" Tag="DocumentsView"> <NavigationViewItem.Icon> <ImageIcon Source="./Assets/Icons/document.png" /> </NavigationViewItem.Icon> </NavigationViewItem> <NavigationViewItemSeparator /> <NavigationViewItem x:Name="NOTAMSViewItem" Content="NOTAMs" FontFamily="Poppins" FontSize="16" FontWeight="Normal" Tag="NOTAMSViews"> <NavigationViewItem.Icon> <ImageIcon Source="./Assets/Icons/warning.png" /> </NavigationViewItem.Icon> </NavigationViewItem> <NavigationViewItemSeparator /> <NavigationViewItem x:Name="SettingsViewItem" Content="Settings" FontFamily="Poppins" FontSize="16" FontWeight="Normal" Tag="SettingsView"> <NavigationViewItem.Icon> <ImageIcon Source="./Assets/Icons/settings.png" /> </NavigationViewItem.Icon> </NavigationViewItem> </NavigationView.MenuItems> <NavigationView.PaneFooter> <StackPanel x:Name="FooterStackPanel" Orientation="Vertical" Visibility="Visible"> <NavigationViewItem AutomationProperties.Name="download" Content="Downloads" FontFamily="Poppins" FontWeight="Normal"> <NavigationViewItem.Icon> <ImageIcon Source="./Assets/Icons/download.png" /> </NavigationViewItem.Icon> </NavigationViewItem> </StackPanel> </NavigationView.PaneFooter> <Grid> <Frame x:Name="contentFrame" HorizontalAlignment="Left" VerticalAlignment="Top" NavigationFailed="contentFrame_NavigationFailed" /> </Grid> </NavigationView> </StackPanel> </Window>
MainWindow.xaml.cs
using Ankara_Online.Views; using Microsoft.UI; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Navigation; using System; using System.Diagnostics; using System.Linq; using Windows.UI.ApplicationSettings; namespace Ankara_Online { public sealed partial class MainWindow : Window { public MainWindow() { this.InitializeComponent(); IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this); var windowId = Win32Interop.GetWindowIdFromWindow(hWnd); var appWindow = AppWindow.GetFromWindowId(windowId); appWindow.Resize(new Windows.Graphics.SizeInt32 { Width = 1200, Height = 900 }); Title = "Ankara Online"; appWindow.SetIcon("Assets\trvacc_icon_transparent.ico"); this.contentFrame = new Frame(); contentFrame.Navigate(typeof(HomePageView)); } private void NavigationView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) { var item = sender.MenuItems.OfType<NavigationViewItem>().First(x => (string)x.Content == (string)args.InvokedItem); NavigationView_Navigate(item as NavigationViewItem); } private void NavigationView_Navigate(NavigationViewItem item) { switch (item.Tag) { case "homePageView": contentFrame.Navigate(typeof(HomePageView)); break; case "softwareSectorFileView": contentFrame.Navigate(typeof(SectorFilesView)); break; case "DocumentsView": contentFrame.Navigate(typeof(DocumentsView)); break; case "NOTAMSViews": contentFrame.Navigate(typeof(NotamsView)); break; case "SettingsView": contentFrame.Navigate(typeof(SettingsView)); break; } } private void contentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) { throw new Exception("Failed to load page " + e.SourcePageType.FullName); } private void NavigationView_Loaded(object sender, RoutedEventArgs args) { this.contentFrame.Navigate(typeof(HomePageView)); } } }
HomePageView.xaml
<Page x:Class="Ankara_Online.Views.HomePageView" 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:local="using:Ankara_Online.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" NavigationCacheMode="Required" mc:Ignorable="d"> <Frame> <Grid ColumnDefinitions="150,*" RowDefinitions="*"> <Image Grid.Row="0" Grid.Column="0" Source="Assets/test_image.png" /> <TextBlock Grid.Row="1" Grid.Column="1" FontFamily="Poppins" FontSize="35" FontWeight="Black" Text="TEST" /> </Grid> </Frame> </Page>
问题原因与解决步骤
1. 覆盖了XAML中定义的contentFrame实例
在MainWindow构造函数中,执行this.contentFrame = new Frame();会创建新的Frame对象,覆盖XAML里已声明的contentFrame。界面显示的是XAML中的Frame,但你导航的是未关联到界面的新Frame,因此导致黑屏。
解决: 删除构造函数中的this.contentFrame = new Frame();,直接使用XAML初始化好的contentFrame实例。
2. HomePageView嵌套了不必要的Frame
HomePageView作为页面,根元素无需嵌套Frame,这会导致内容被包裹在未正确显示的Frame里无法渲染。同时原代码中TextBlock的Grid.Row=1超出了网格范围(仅定义1行),也会导致文本无法显示。
解决: 修改HomePageView.xaml,去掉外层Frame并修正TextBlock的Grid.Row值:
<Page x:Class="Ankara_Online.Views.HomePageView" 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:local="using:Ankara_Online.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" NavigationCacheMode="Required" mc:Ignorable="d"> <Grid ColumnDefinitions="150,*" RowDefinitions="*"> <Image Grid.Row="0" Grid.Column="0" Source="Assets/test_image.png" /> <TextBlock Grid.Row="0" Grid.Column="1" FontFamily="Poppins" FontSize="35" FontWeight="Black" Text="TEST" /> </Grid> </Page>
3. 优化NavigationView项的查找逻辑
原代码通过Content匹配查找NavigationViewItem,当Content重复或格式变化时易出错,可直接通过args.InvokedItemContainer获取被点击项:
private void NavigationView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) { if (args.InvokedItemContainer is NavigationViewItem item) { NavigationView_Navigate(item); } }
4. 确保初始导航生效
删除新建Frame的代码后,可在InitializeComponent()之后直接添加导航代码,或保留NavigationView_Loaded事件中的导航,确保程序启动时contentFrame正确加载HomePageView。
内容的提问来源于stack exchange,提问作者cptalpdeniz

