1. Avalonia v11初体验:为什么选择这个跨平台UI框架?
第一次接触Avalonia是在去年一个需要同时支持Windows和macOS的项目中。当时尝试过几种跨平台方案,要么性能堪忧,要么开发体验差强人意。直到同事推荐了Avalonia,用他的话说就是"像写WPF一样写跨平台应用",这句话让我决定试一试。
Avalonia v11最吸引我的就是它真正的"一次编写,到处运行"能力。不像某些框架只是简单封装原生控件,Avalonia有自己的渲染引擎,这意味着你在Windows上设计的UI,在macOS、Linux甚至手机上看起来几乎一模一样。我最近用v11重做了公司内部的一个工具,从桌面端到移动端只用了两周时间,这在以前至少要两个月。
安装过程比想象中简单很多。在Visual Studio的扩展管理中搜索"Avalonia",会看到两个关键组件:Avalonia for Visual Studio 2022和Avalonia Template Studio。建议两个都安装,前者是核心支持,后者提供了项目模板和脚手架工具。安装完成后需要重启VS,这点和其他扩展没什么不同。
2. 创建你的第一个跨平台项目
创建新项目时,在Visual Studio的模板选择器中能找到Avalonia分类。v11的模板比之前版本简洁很多,只有一个"Avalonia Application"选项。别被这个简单界面迷惑,接下来的配置才是重点。
项目创建向导会询问目标平台,这是v11最强大的地方——可以同时勾选Desktop、Android、iOS和WebAssembly。我建议初次使用时先只选Desktop,等熟悉了再添加其他平台。有趣的是,即使用户界面代码完全一样,Avalonia也会为每个平台生成独立的启动项目,这是为了处理各平台的特定配置。
生成的项目结构很清晰:主项目AvaloniaApp包含共享的视图和业务逻辑,AvaloniaApp.Desktop等平台项目只包含启动配置。这种架构让代码复用率极高,我在实际项目中能达到85%以上的代码共享率。记得第一次看到同一套UI同时在Windows程序和安卓手机上运行时,团队里的小伙伴都惊呆了。
3. 桌面端部署实战:Windows和macOS
桌面端部署是最简单的部分。在AvaloniaApp.Desktop项目中,Program.cs文件里的BuildAvaloniaApp方法就是入口。v11在这里有个很棒的改进——默认启用了Skia渲染后端,这让应用在不同操作系统上看起来更一致。
打包Windows应用时,我习惯用ClickOnce发布。在项目属性里配置好发布选项后,一个简单的右键发布就能生成安装包。macOS稍微麻烦些,需要先创建.app bundle。命令行工具dotnet publish加上-r osx-x64参数可以生成原生包,然后用codesign命令签名就能分发。
遇到过的一个坑是跨平台字体渲染问题。解决方案是在App.axaml里显式指定字体栈:
<FontFamily>avares://AvaloniaApp/Assets/Fonts#Roboto, Microsoft YaHei, PingFang SC</FontFamily>这样会优先使用内嵌的Roboto字体,回退到各平台的系统字体。
4. 移动端适配技巧:Android和iOS
移动端开发需要先配置好环境:Android SDK和Xcode是必须的。v11对移动端的支持比之前版本成熟很多,特别是手势识别和软键盘交互都有了很大改进。
Android项目需要注意屏幕适配。Avalonia使用与Xamarin相同的DPI计算方式,在MainActivity.cs中可以通过设置ContentPage的WidthRequest和HeightRequest来控制初始尺寸。我通常会加一个全局样式来适配不同屏幕:
<Style Selector="ContentControl"> <Setter Property="HorizontalAlignment" Value="Stretch"/> <Setter Property="VerticalAlignment" Value="Stretch"/> </Style>iOS部署有个特别要注意的地方——必须配置Entitlements.plist文件。特别是需要网络访问的应用,要添加相应的权限声明。Xcode 14之后还需要在Signing & Capabilities中添加Sandbox例外。
5. 发布到Web:WASM实战
WebAssembly支持是v11的王牌功能之一。创建项目时勾选WebAssembly选项会生成一个AvaloniaApp.Web项目。这个项目的wwwroot目录就是最终部署的内容。
调试WASM应用有个小技巧:在launchSettings.json中配置"inspectUri",这样可以在浏览器开发者工具中调试C#代码。发布时运行dotnet publish -c Release -r browser-wasm命令,生成的dist目录可以直接部署到任何Web服务器。
遇到过的一个性能问题是首次加载慢。解决方案有两个:启用AOT编译(虽然会增大包体积),或者配置WASM延迟加载。在Web项目的Program.cs中添加以下代码可以显著提升加载速度:
builder.UseAvaloniaApp(() => { var app = new App(); app.Startup += (s, e) => LoadImportantModulesAsync(); return app; });6. 项目配置的进阶技巧
Avalonia v11的配置系统非常灵活。appsettings.json仍然是配置首选,但v11增加了平台特定的配置覆盖功能。比如可以在Android项目的Assets文件夹放一个appsettings.android.json,运行时会自动合并配置。
依赖注入也有改进。现在可以在AppBuilder中直接配置Services:
BuildAvaloniaApp() .WithInterFont() .UsePlatformDetect() .ConfigureServices(services => { services.AddSingleton<IApiService, ApiService>(); }) .StartWithClassicDesktopLifetime(args);多语言支持现在更简单了。在项目根目录创建Resources文件夹,放入.resx文件,然后在视图中使用{x:Static}标记即可:
<TextBlock Text="{x:Static res:Resources.WelcomeMessage}"/>7. 调试与性能优化
跨平台调试的关键是合理使用条件编译。Avalonia v11定义了多个平台常量:
#if ANDROID // Android特定代码 #elif IOS // iOS特定代码 #endif性能分析工具链很完善。桌面端可以用Visual Studio自带的诊断工具,移动端推荐使用Avalonia.Diagnostics包。在代码中添加:
AppBuilder.Configure<App>() .UseDiagnostics() // 添加这行 .UsePlatformDetect() .StartWithClassicDesktopLifetime(args);运行时按F7可以打开诊断面板,查看可视化树和渲染性能。
内存管理方面,要注意跨平台图像处理。建议使用新的Bitmap类替代之前的WriteableBitmap,它在所有平台都有更好的表现:
using var stream = File.OpenRead("image.png"); var bitmap = new Bitmap(stream); image.Source = bitmap;8. 实际项目中的经验分享
在电商App项目中,我们遇到最棘手的问题是列表滚动性能。v11的虚拟化控件解决了这个问题。正确的用法是:
<ItemsControl Items="{Binding Products}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl>另一个常见痛点是主题切换。v11的样式系统支持运行时切换:
Application.Current.Styles[0] = new DarkTheme(); // 或者 Application.Current.Styles[0] = new LightTheme();导航系统我们选择了ReactiveUI配合Avalonia的路由视图:
// 注册路由 Routing.RegisterRoute("login", typeof(LoginView)); // 导航到页面 Router.Navigate.Execute(new LoginViewModel());最后给个实用建议:在解决方案中放一个Shared项目,存放所有平台通用的DTO和服务接口。这样不仅UI可以共享,业务逻辑也能最大程度复用。我们最近的项目中,90%的代码库都在Shared项目中,各平台项目只包含必要的适配层代码。