一个 .NET 工程同时跑 Windows、macOS 和 Linux:Avalonia 跨平台 UI 实战指南
【免费下载链接】AvaloniaDevelop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The future of .NET UI项目地址: https://gitcode.com/GitHub_Trending/ava/Avalonia
Avalonia 是一个用 C# 和 XAML 开发桌面、嵌入式、移动和 WebAssembly 应用的 .NET 跨平台 UI 框架,支持 Windows、macOS、Linux、iOS、Android 与 WebAssembly,常被开发者视为 WPF 的跨平台延续。本文按真实开发流程,从选型、搭建项目到常用组件与排查问题,带你完整走一遍。
先看它适合做什么
在动手前,先确认 Avalonia 与你的场景匹配:
- 同一套 C#/XAML 代码覆盖多平台。仓库中每个示例应用都采用"一个共享工程 + 各平台入口工程"的组织方式,比如 samples/ControlCatalog.Desktop/、samples/ControlCatalog.Android/、samples/ControlCatalog.Browser/,共享部分全部放在 samples/ControlCatalog/。
- XAML 开发者转型成本低。布局、绑定、样式、模板等概念与 WPF 一致,但并非逐行复制,实现上有不少改进(见 readme.md 中的说明)。
- 成熟度可查证。项目通过 NuGet 分发,docs/api-compat.md 中写明其在主版本内保持严格的源码与二进制兼容,且每次 CI 都会自动做 API 兼容性检查。
如果目标只是把现有 WPF 应用原样移植到 macOS/Linux,README 提到商业产品 Avalonia XPF 更适合该诉求,本文不展开。
项目结构:一个工程如何同时跑三端
以 samples/SingleProjectSandbox/ 为参照,单工程多目标的核心写法在 csproj 中:
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsCurrentAndroidTargetFramework);$(AvsCurrentBrowserTargetFramework)</TargetFrameworks>加上<AvaloniaSingleProject>true</AvaloniaSingleProject>,即可让 desktop、Android、浏览器(WASM)共用一份界面代码,平台差异集中在Platforms/目录(如 samples/SingleProjectSandbox/Platforms/)下的入口文件里。
启动代码非常短,samples/Sandbox/Program.cs 展示了最小入口:
public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>() .UsePlatformDetect() #if DEBUG .WithDeveloperTools() #endif .LogToTrace();三个要点:
AppBuilder.Configure<App>()指定 Application 类;UsePlatformDetect()根据运行环境选择对应平台后端;- 调试期开启
WithDeveloperTools()可获得开发辅助工具,日志通过LogToTrace()输出。
桌面端最后调用StartWithClassicDesktopLifetime(args)启动窗口生命周期,其他平台(Android、iOS、浏览器)则使用各自的 Lifetime 入口。
常用组件实战:按场景归类
以下控件均来自仓库实际 API,用法示例参考 samples/ControlCatalog/Pages/(400+ 页面,是学习控件用法最快的地方)。
📐 SplitView:侧边栏响应式布局
SRC 源码 中的SplitView用于"侧边导航 + 主内容"布局,四个显示模式定义在 SplitViewDisplayMode.cs:
| 模式 | 行为 |
|---|---|
Inline | 面板并排显示,点击外部不自动收起 |
CompactInline | 收起后仍保留CompactPaneLength宽度的残影 |
Overlay | 面板悬浮在内容之上,点击外部自动收起 |
CompactOverlay | 悬浮 + 收起后保留残影 |
XAML 基本结构:
<SplitView IsPaneOpen="True" DisplayMode="Inline" PaneOpening="OnPaneOpening"> <SplitView.Pane> <ListBox /> </SplitView.Pane> <StackPanel Margin="16"> <!-- 主内容 --> </StackPanel> </SplitView>常见的自适应写法:在窗口SizeChanged中切换模式——宽屏用Inline,窄屏切到Overlay并收起面板,让导航不挤占内容区。
🍔 NativeMenuBar:跟随系统规范的菜单栏
系统级菜单用NativeMenuBar+NativeMenuItem声明,samples/ControlCatalog/DecoratedWindow.xaml 给出了完整示例:
<NativeMenuItem Header="File"> <NativeMenuItem Header="Open" Click="OnOpenClicked" Gesture="Ctrl+O"/> <NativeMenuItemSeparator/> <NativeMenuItem Header="Quit Avalonia" Gesture="CMD+Q"/> </NativeMenuItem>注意两点:
Gesture属性支持Ctrl+O、CMD+Q这类平台化快捷键写法;- 菜单项支持
ToggleType="Radio/CheckBox"、IsEnabled、IsVisible、图标与Command绑定(见 samples/ControlCatalog/App.xaml),在 macOS 上会融合进系统菜单栏,行为与各平台规范保持一致。
🪟 嵌入与互操作
- 需要嵌入平台原生控件时,使用 src/Avalonia.Controls/NativeControlHost.cs,Linux 侧的 X11 嵌入示例见 samples/XEmbedSample/;
- 直接操作 GPU 互操作(D3D、Vulkan)参考 samples/GpuInterop/。
macOS 原生后端如何调试
macOS 平台后端含 Objective-C 原生组件,位于 native/Avalonia.Native/src/OSX/。修改原生代码后不必触发整个 Avalonia 重新编译:用 Xcode 编译项目后,把产物路径(Xcode 的 "Products" 面板可见)通过AvaloniaNativePlatformOptions.AvaloniaNativeLibraryPath注入即可,方法来自 docs/macos-native.md:
public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>() .UsePlatformDetect() .With(new AvaloniaNativePlatformOptions { AvaloniaNativeLibraryPath = "[Path to your dylib]", })Xcode 中定位产物路径的位置如下(截图引自官方文档):
另外,若需要在 Xcode 的 Accessibility Inspector 中测试 macOS 辅助功能,应用必须以 .app bundle 形式运行。samples/IntegrationTestApp/bundle.sh 提供了现成的打包脚本,其他工程可修改输出路径模拟 bundle 结构(详见 docs/macos-native.md 的 "Bundling Development Code" 一节)。
常见问题与排查思路
按 docs/build.md 与仓库构建脚本整理,源码级开发(而非仅使用 NuGet 包)时最可能遇到三类问题:
- Submodule 未同步。克隆仓库时必须
git clone --recurse-submodules https://gitcode.com/GitHub_Trending/ava/Avalonia,更新后执行git submodule update --init --recursive,否则会缺外部依赖(如 external/ 下的 XamlX、Avalonia.DBus)。 - MSB4062 / GenerateAvaloniaResourcesTask 报错。说明构建任务程序集未编译,手动先构建一次
Avalonia.Build.Tasks工程,或用 Nuke 完整构建一次解决方案。 - XAML 编译行为不符合预期。仓库提供了专门的排查文档 docs/debug-xaml-compiler.md,讲解如何定位 XAML 编译器在构建管道中的位置与中间产物。
SDK 版本由 global.json 锁定(当前要求 .NET SDK 10.0.201,rollForward: latestFeature),构建前请确认本机 SDK 兼容;IDE 方面,docs/build.md 建议使用支持 .NET 10 的 Visual Studio 2026 或 Rider 2025.3 及以上版本,并区分两个入口:完整解决方案Avalonia.slnx(含移动端与 Web,需安装对应 workload)和仅桌面部分的Avalonia.Desktop.slnf(无需额外 workload)。
深入学习路径
建议按这个顺序推进:
- 跑起示例:构建并运行
ControlCatalog.Desktop,浏览 samples/ControlCatalog/Pages/ 中的控件演示,对照 samples/ControlCatalog/ViewModels/ 看数据绑定写法; - 理解构建体系:通读 docs/build.md(Nuke 构建、
nuke --target Compile/RunTests/Package)与 docs/nuget.md(本地打包); - 理解兼容性承诺:docs/api-compat.md 说明 API 兼容保证与破坏性变更的批准流程;
- 参与贡献:阅读 CONTRIBUTING.md 与 CODE_OF_CONDUCT.md,第三方代码移植可参考 docs/porting-code-from-3rd-party-sources.md。
更多使用层面的教程以官方文档站 docs.avaloniaui.net 为准,本仓库内的 docs/index.md 则是面向框架开发者的文档索引。
【免费下载链接】AvaloniaDevelop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The future of .NET UI项目地址: https://gitcode.com/GitHub_Trending/ava/Avalonia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考