.NET Maui中Navigation.PushAsync跳转页面空白问题排查
问题描述
将Xamarin Forms(XF)应用迁移至.NET MAUI后,出现以下异常情况:
- 导航栏中定义的
ToolbarItem点击后,跳转的EventSetupPage在Android 12模拟器中显示空白,但页面构造函数已被正常调用。 - 父页面通过
MessagingCenter消息触发加载,相关代码如下:
父页面ToolbarItem定义
<ContentPage.ToolbarItems> <ToolbarItem Text="New Game" Clicked="NewGame_Clicked" x:Name="NewGame" /> </ContentPage.ToolbarItems> <VerticalStackLayout><ListView........./></VerticalStackLayout>
点击事件代码
private void NewGame_Clicked(object sender, EventArgs e) { Navigation.PushAsync(new EventSetupPage()); }
EventSetupPage简化代码
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ScanAndScoringMauiApp.Pages.EventSetupPage" Title="EventSetupPage"> <VerticalStackLayout> <Label Text="Welcome to .NET MAUI!" VerticalOptions="Center" HorizontalOptions="Center" /> </VerticalStackLayout> </ContentPage>
父页面加载逻辑
MessagingCenter.Subscribe<string>(this, "UpdateMainPage", (sender) => { MainThread.BeginInvokeOnMainThread(() => { MainPage = new NavigationPage(new GameList()); }); });
解决方案
1. 显式在主线程执行导航操作
尽管PushAsync默认会处理线程切换,但在MessagingCenter触发的页面上下文中,显式包裹主线程调用可避免渲染异常:
private async void NewGame_Clicked(object sender, EventArgs e) { await MainThread.InvokeOnMainThreadAsync(() => Navigation.PushAsync(new EventSetupPage()) ); }
2. 验证Navigation实例有效性
确保当前页面的Navigation属性不为null,若为空则重新通过Application.Current.MainPage设置导航容器:
private async void NewGame_Clicked(object sender, EventArgs e) { if (Navigation == null) { await MainThread.InvokeOnMainThreadAsync(() => { Application.Current.MainPage = new NavigationPage(new EventSetupPage()); }); return; } await MainThread.InvokeOnMainThreadAsync(() => Navigation.PushAsync(new EventSetupPage()) ); }
3. 替换MessagingCenter为WeakReferenceMessenger(官方推荐)
.NET MAUI中MessagingCenter已被标记为过时,改用WeakReferenceMessenger可避免内存泄漏和线程问题:
- 安装
CommunityToolkit.MvvmNuGet包 - 修改消息发送与订阅逻辑:
using CommunityToolkit.Mvvm.Messaging; // 发送消息(替代原MessagingCenter.Send) WeakReferenceMessenger.Default.Send("UpdateMainPage"); // 订阅消息(替代原MessagingCenter.Subscribe) WeakReferenceMessenger.Default.Register<string>(this, (recipient, message) => { MainThread.BeginInvokeOnMainThread(() => { Application.Current.MainPage = new NavigationPage(new GameList()); }); });
4. 检查Android项目配置
确保MainActivity正确继承MauiAppCompatActivity,无自定义导航拦截:
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] public class MainActivity : MauiAppCompatActivity { }
5. 清理模拟器缓存并重启
Android模拟器缓存可能导致页面渲染异常,执行以下操作:
- 关闭模拟器,在Android Device Manager中选择对应模拟器,点击"清空数据"
- 重启Visual Studio和模拟器,重新编译运行项目
内容的提问来源于stack exchange,提问作者Wallace B. McClure
相关产品推荐
相关产品推荐

