Avalonia 支持跨平台开发,但有时需要为不同操作系统(如 Windows、macOS、Linux)编写特定逻辑或 UI 行为。它不提供类似 Xamarin 的
OnPlatformXAML 语法,但有更灵活、更符合 .NET 生态的方式实现平台特定代码。
使用 Avalonia 的 RuntimePlatform 检测当前平台
最直接的方式是通过
Avalonia.Application.Current.ApplicationLifetime或静态属性
Avalonia.Threading.Dispatcher.UIThread.InvokeAsync中检查运行时平台:
RuntimePlatform.IsWindows
RuntimePlatform.IsMacOS
RuntimePlatform.IsLinux
这些是编译时已知的常量(基于目标框架),适合在初始化、资源加载、窗口行为等场景做轻量判断。例如:
if (RuntimePlatform.IsMacOS)
{
mainWindow.ExtendClientAreaToDecorationsHint = true;
mainWindow.SystemDecorations = SystemDecorations.None;
}用条件编译(#if)分离平台专用实现
对于差异较大、涉及 P/Invoke、原生 API 调用或平台专属服务(如通知、托盘图标),推荐用 C# 条件编译:
在项目文件中为不同平台定义符号(如<defineconstants>$(DefineConstants);MACOS</defineconstants>) 或依赖 SDK 自动定义:
WINDOWS、
MACOS、
LINUX(Avalonia SDK 默认启用)
然后在代码中:
#if WINDOWS var tray = new WinTrayIcon(); #elif MACOS var tray = new MacTrayIcon(); #elif LINUX var tray = new LinuxTrayIcon(); #endif
通过依赖注入注册平台专用服务
更推荐的架构方式:定义统一接口(如
INotificationService),并在
AppBuilder配置阶段按平台注册不同实现:
var builder = AppBuilder.Configure<App>()
.UsePlatformDetect()
.SetupWithoutStarting();
<p>if (RuntimePlatform.IsWindows)
builder.Services.AddSingleton<INotificationService, WindowsNotificationService>();
else if (RuntimePlatform.IsMacOS)
builder.Services.AddSingleton<INotificationService, MacNotificationService>();
else
builder.Services.AddSingleton<INotificationService, LinuxNotificationService>();</p><p>builder.Start();这样业务逻辑完全解耦,测试和维护更清晰。
平台特定资源与样式(XAML 层)
Avalonia 不支持 XAML 内联平台判断,但可通过以下方式适配:
在App.xaml中按需
Merge不同平台的资源字典(如
Styles.Windows.xaml) 用
Style Selector+ 自定义
IStyleSelector在运行时切换样式 对控件属性绑定一个平台感知的 ViewModel 属性(如
IsMacOs => IsTransparentBackground = true)
例如,在窗口 XAML 中:
<Window.Styles>
<StyleInclude Source="resm:MyApp.Styles.Windows.xaml?assembly=MyApp"
Condition="{x:Static platform:RuntimePlatform.IsWindows}" />
<StyleInclude Source="resm:MyApp.Styles.MacOS.xaml?assembly=MyApp"
Condition="{x:Static platform:RuntimePlatform.IsMacOS}" />
</Window.Styles>注意:
platform:需在 XAML 命名空间中声明:
xmlns:platform="using:Avalonia"。
