Xe.Prism.Avalonia.Mobile.Android 1.1.7

dotnet add package Xe.Prism.Avalonia.Mobile.Android --version 1.1.7
                    
NuGet\Install-Package Xe.Prism.Avalonia.Mobile.Android -Version 1.1.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Xe.Prism.Avalonia.Mobile.Android" Version="1.1.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Xe.Prism.Avalonia.Mobile.Android" Version="1.1.7" />
                    
Directory.Packages.props
<PackageReference Include="Xe.Prism.Avalonia.Mobile.Android" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Xe.Prism.Avalonia.Mobile.Android --version 1.1.7
                    
#r "nuget: Xe.Prism.Avalonia.Mobile.Android, 1.1.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Xe.Prism.Avalonia.Mobile.Android@1.1.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Xe.Prism.Avalonia.Mobile.Android&version=1.1.7
                    
Install as a Cake Addin
#tool nuget:?package=Xe.Prism.Avalonia.Mobile.Android&version=1.1.7
                    
Install as a Cake Tool

Prism.Avalonia.Mobile

MAUI-aligned page navigation framework for Avalonia 12+, designed for mobile-first, AOT-compatible cross-platform applications.


架构概述

┌──────────────────────────────────────────────────────┐
│  INavigationService         页面级导航               │
│  NavigateAsync / GoBack / GoBackTo / SelectTab       │
│                                                      │
│  ┌────────────────────────────────────────────────┐  │
│  │  NavigationPage (Avalonia 12)                  │  │
│  │  ┌──────┐  ┌──────┐  ┌──────┐               │  │
│  │  │ Page │  │ Page │  │ Page │   Push/Pop     │  │
│  │  └──────┘  └──────┘  └──────┘               │  │
│  │  ┌──────────────────────────────────────────┐│  │
│  │  │  IRegionManager  区域导航                 ││  │
│  │  │  ContentControl / ItemsControl Regions   ││  │
│  │  └──────────────────────────────────────────┘│  │
│  └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘

双导航系统:

  • INavigationService — 页面级导航 (Push/Pop/Modal),用于页面跳转
  • IRegionManager — 区域导航,用于页面内部的组合视图切换

快速开始

1. 安装

dotnet add package Prism.Avalonia.Mobile
dotnet add package Prism.DryIoc.Avalonia.Mobile

或直接引用项目:

<ProjectReference Include="..\..\..\src\Prism.Avalonia.Mobile\Prism.Avalonia.Mobile.csproj" />
<ProjectReference Include="..\..\..\src\Prism.DryIoc.Avalonia.Mobile\Prism.DryIoc.Avalonia.Mobile.csproj" />

2. 创建 App

// App.axaml.cs
using Avalonia.Controls;
using Prism.DryIoc;
using Prism.Ioc;

public partial class App : PrismApplication
{
    protected override AvaloniaObject CreateShell()
    {
        return new NavigationPage
        {
            Content = Container.Resolve<MainPage>()
        };
    }

    protected override void RegisterTypes(IContainerRegistry cr)
    {
        // 方式 A: 属性标注,一行注册所有 [PrismView] 视图
        cr.RegisterPrismViews();

        // 方式 B: 代码注册(与 nameof 配合,编译期安全)
        // cr.RegisterForNavigation<MainPage, MainViewModel>();       // → "MainPage"
        // cr.RegisterForNavigation<DetailPage, DetailViewModel>();   // → "DetailPage"
    }
}

3. 导航

public class MainViewModel
{
    private readonly INavigationService _nav;
    
    public MainViewModel(INavigationService navigationService)
    {
        _nav = navigationService;
    }

    public async Task GoToDetail()
    {
        // URI 导航
        await _nav.NavigateAsync("DetailPage?id=5&name=hello");

        // nameof + 参数 (编译期安全,推荐)
        await _nav.NavigateAsync(nameof(DetailPage),
            new NavigationParameters { { "id", 5 }, { "name", "hello" } });

        // Builder API
        await _nav.CreateBuilder()
            .AddSegment(nameof(DetailPage), s => s.AddParameter("id", 5))
            .NavigateAsync();
    }
}

功能一览

功能 API 说明
页面导航 NavigateAsync("PageName?param=value") URI 分段导航,支持参数
GoBack GoBackAsync() 回退上一页
GoBackTo GoBackToAsync("PageName") 回退到指定页面
GoBackToRoot GoBackToRootAsync() 回退到导航栈根
Tab 选择 SelectTabAsync("TabName") 编程切换 Tab
Builder CreateBuilder().AddSegment().NavigateAsync() 流式 API 构建导航
生命周期 INavigatedAware / IInitialize / IConfirmNavigation 页面导航生命周期
页面行为 IPageBehaviorFactory 页面作用域/激活感知/生命周期
区域导航 IRegionManager.RequestNavigate("RegionName", uri) ContentControl/ItemsControl 切换
对话框 IDialogService.ShowDialog / ShowInline / ShowWindow 内嵌模态 / 外部窗口
模块化 IModuleManager / IModuleCatalog 模块化加载
AOT 显式注册 + 源生成器 支持 Native AOT 编译

对话框

// 内嵌弹出 (NavigationPage.PushModalAsync) — 移动端推荐
_dialogService.ShowInline("DemoDialog", parameters,
    new DialogCallback().OnClose(result =>
    {
        if (result.Result == ButtonResult.OK)
        {
            var input = result.Parameters.GetValue<string>("userInput");
        }
    }));

// 外部窗口 — 仅桌面端
_dialogService.ShowWindow("DemoDialog", parameters, callback);

// 自动选择 (移动端=内嵌, 桌面端=窗口)
_dialogService.ShowDialog("DemoDialog", parameters, callback);

// 配置遮罩点击关闭
var p = new DialogParameters
{
    { KnownDialogParameters.CloseOnBackdropTap, false }
};

对话框 ViewModel

public class DemoViewModel : BindableBase, IDialogAware
{
    private IDialogCloser? _closer;
    public DelegateCommand CloseCommand { get; }
    public DelegateCommand CancelCommand { get; }

    public DemoViewModel()
    {
        CloseCommand = new(() => _closer?.Close(new DialogResult
        {
            Result = ButtonResult.OK,
            Parameters = new DialogParameters { { "userInput", Input } }
        }));
        CancelCommand = new(() => _closer?.Close(new DialogResult
        {
            Result = ButtonResult.Cancel
        }));
    }

    public void OnDialogOpened(IDialogParameters p)
    {
        p.TryGetValue<IDialogCloser>(KnownDialogParameters.DialogCloser, out _closer);
    }
}

Region 区域导航


<ContentControl prism:RegionManager.RegionName="ContentRegion" />
// 注册区域视图
cr.RegisterForNavigation<DashboardView, DashboardViewModel>("DashboardView");

// 导航到区域
_regionManager.RequestNavigate("ContentRegion", 
    new Uri("DashboardView", UriKind.Relative));

AOT 配置

1. 推荐方式:[PrismView] 属性标注 + RegisterPrismViews()

标注视图:

using Prism;
using Prism.Mvvm;

// Page — 默认 ViewType.Page
[PrismView("MainPage", ViewModel = typeof(MainViewModel))]
public partial class MainPage : ContentPage { }

// Region
[PrismView("DashboardView", ViewModel = typeof(DashboardViewModel), ViewType = ViewType.Region)]
public partial class DashboardView : UserControl { }

// Dialog
[PrismView("DemoDialog", ViewModel = typeof(DemoViewModel), ViewType = ViewType.Dialog)]
public partial class DemoDialog : UserControl, IDialogAware { }

一行注册:

protected override void RegisterTypes(IContainerRegistry cr)
{
    cr.RegisterPrismViews(); // SourceGen 生成,自动注册所有 [PrismView] 视图
}

2. 备选方式:RegisterForNavigation 代码注册

偏好显式控制的用户可以用传统方式,与 nameof 配合实现编译期安全:

protected override void RegisterTypes(IContainerRegistry cr)
{
    cr.RegisterForNavigation<MainPage, MainViewModel>();       // name: "MainPage"
    cr.RegisterForNavigation<DetailPage, DetailViewModel>();   // name: "DetailPage"
}

// 导航时
_nav.NavigateAsync(nameof(DetailPage), parameters); // 编译期安全

3. 混合使用

两种方式可共存,不冲突:

protected override void RegisterTypes(IContainerRegistry cr)
{
    cr.RegisterPrismViews();                                    // 属性标注的
    cr.RegisterForNavigation<SettingsPage>("SettingsPage");     // 代码注册的
}

等效对比:

注册方式 代码量 AOT 安全 编译期检查
[PrismView] + RegisterPrismViews() 属性 + 一行调用 ✅ ✅ SourceGen
RegisterForNavigation<T>() 每个 View 一行 ✅ ✅ 泛型
混合 灵活搭配 ✅ ✅

4. [PrismView] 属性参数

参数 类型 默认 说明
navigationName string? 类名 导航名称,对应 NavigateAsync 的 URI
ViewModel Type? null ViewModel 类型,SourceGen 自动生成映射
ViewType ViewType Page 视图类型

5. ViewType 枚举

值 导航方式 典型控件
Page INavigationService ContentPage, NavigationPage
Region IRegionManager UserControl → ContentControl / ItemsControl
Dialog IDialogService UserControl → IDialogAware

6. 源生成器编译流程

编译时                                  运行时
───────                                ──────
[PrismView] 属性                        |
    ↓                                  |
NavigationRegistryGenerator 解析        |
    ├── PrismViewRegistrar.g.cs        |   cr.RegisterPrismViews() 调用
    │    (DI 注册代码) ───────────────────→ 注册 View + ViewModel 到容器
    │                                   |
    └── ViewRegistrationSource.g.cs    |   NavigationRegistry 消费
         (元数据工厂) ───────────────────→ CreateView() 零反射查找

7. DryIoc 容器 AOT 规则

protected override Rules CreateContainerRules()
{
    return Rules.Default
        .WithConcreteTypeDynamicRegistrations((_, _) => false)
        .WithAutoConcreteTypeResolution(false);
}

8. 已被禁用的反射路径

反射 API 替代方案
Type.GetType(name) [PrismView] + SourceGen
Activator.CreateInstance(type) DI 容器 Resolve(type)
Assembly.GetTypes() 扫描 SourceGen 编译时
约定命名 Views.Xxx → ViewModels.Xxx ViewModel 参数显式指定

返回拦截 (Back Navigation Guard)

程序化拦截:IConfirmNavigation

在 ViewModel 中实现 IConfirmNavigation,CanNavigate 返回 false 即可阻止所有后退操作。

public class EditViewModel : BindableBase, IConfirmNavigation
{
    private bool _hasUnsavedChanges;

    /// <summary>
    /// 在任何后退操作之前调用(GoBack/GoBackTo/GoBackToRoot/系统返回键/侧滑)
    /// 返回 false 阻止导航。
    /// </summary>
    public bool CanNavigate(INavigationParameters parameters)
    {
        if (_hasUnsavedChanges)
            return false;  // 阻止后退
        return true;
    }
}

被拦截的后退操作:

操作 是否拦截
_nav.GoBackAsync() ✅
_nav.GoBackToAsync("Page") ✅
_nav.GoBackToRootAsync() ✅
Android 系统返回键 ✅
侧滑返回手势 ⚠️ 框架捕获事件,但物理手势本身无法取消

物理手势拦截:禁用侧滑

侧滑手势由 Avalonia 12 原生处理,IConfirmNavigation 在 Pop 事件后触发。要阻止物理手势本身,需禁用侧滑:


<ContentPage NavigationPage.IsGestureEnabled="False" />


<NavigationPage IsGestureEnabled="False" />
// 代码: 根据状态动态切换
NavigationPage.SetIsGestureEnabled(this, !_hasUnsavedChanges);

完整示例:编辑页面(Demo 中可运行)

Demo 操作:
  主页 → "Back Guard" → "Open Edit Page"
  → 勾选 "I have made changes"
  → 点 "Go Back" / 按返回键 / 侧滑
  → 被阻止,显示 "Back blocked — you have unsaved changes"
  → 取消勾选 → 后退恢复正常
// View
[PrismView("EditPage", ViewModel = typeof(EditViewModel))]
public partial class EditPage : ContentPage { ... }

// ViewModel
public class EditViewModel : BindableBase, IConfirmNavigation
{
    private bool _hasChanges;

    public bool CanNavigate(INavigationParameters parameters)
        => !_hasChanges; // true = 允许, false = 阻止

    public async Task TryGoBack()
    {
        var result = await _nav.GoBackAsync();
        if (!result.Success)
            Console.WriteLine("Back was blocked!");
    }
}

两种拦截时机

程序化返回 (_nav.GoBackAsync)
  → CanNavigateAsync() 检查 IConfirmNavigation
    → false: 抛出 NavigationException,导航取消
    → true:  正常后退

物理手势 / 系统返回键
  → Avalonia 原生手势识别 → Popped 事件
  → PageSystemBackBehavior 捕获 Popped
  → CanNavigateAsync() 检查
    → false: 返回 NavigationException,但页面已经 Pop 了一半
    → 建议: 在手势场景下配合 IsGestureEnabled=false 使用

Demo 项目

samples/SampleApp/
├── SampleApp/             共享库 (XAML Views + ViewModels)
├── SampleApp.Desktop/     Windows / macOS / Linux
├── SampleApp.Android/     Android
├── SampleApp.iOS/         iOS
└── SampleApp.Browser/     WebAssembly

运行:

# Desktop
dotnet run --project samples/SampleApp/SampleApp.Desktop

# Android (需 workload)
dotnet build -t:Run -f net10.0-android samples/SampleApp/SampleApp.Android

Android 系统返回键拦截

⚠️ 必读:Avalonia 12 的 NavigationPage 在 Android 上不拦截系统返回键(边缘滑动/物理返回键总是直接关闭 Activity)。需要安装本可选包来修复。

安装(可选但推荐)

dotnet add package Xe.Prism.Avalonia.Mobile.Android

使用

将 MainActivity 的基类从 AvaloniaMainActivity 改为 PrismAvaloniaMainActivity:

using Prism.Platforms.Android;

[Activity(Label = "MyApp", MainLauncher = true,
    ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : PrismAvaloniaMainActivity
{
    // 你的自定义代码(相机初始化、权限等)保持不变
}

效果

用户操作 行为
子页面返回键 / 边缘滑动 NavigationPage.PopAsync() → 回退上一页
对话框打开时返回键 NavigationPage.PopModalAsync() → 关闭对话框
根页面返回键 / 边缘滑动 base.OnBackPressed() → 关闭 Activity(退出 App)

不需要重写 OnBackPressed,PrismAvaloniaMainActivity 自动处理。


平台支持

平台 状态
Windows ✅ Desktop
macOS ✅ Desktop
Linux ✅ Desktop
Android ✅
iOS ✅
Browser (WASM) ✅

依赖

NuGet 说明
Prism.Core 核心接口/抽象
Prism.Container.DryIoc DryIoc DI 容器
Xe.Prism.Avalonia.Mobile.Android Android 返回键拦截(可选)

不使用 Prism.Core 源码——全部通过 NuGet 引用。


与 Prism MAUI 的区别

特性 Prism MAUI Prism.Avalonia.Mobile
Shell ✅ ❌ (Avalonia 无对应)
FlyoutPage ✅ DrawerPage (API 不同)
NavigationPage ✅ ✅
TabbedPage ✅ ⚠️ (API 差异)
INavigationService ✅ ✅ 100% 对齐
Region ✅ ✅
Dialog ✅ ✅
AOT ❌ ✅
Product Compatible and additional computed target framework versions.
.NET net10.0-android36.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.7 115 8/7/2026
1.1.6 108 8/7/2026
1.1.5 128 7/5/2026