C# Avalonia怎么获取屏幕分辨率 Avalonia Screen信息

在Avalonia中通过Screen类和Screens静态集合跨平台获取屏幕信息:Screens.Primary获取主屏DIP尺寸、DPI、WorkingArea;Screens.All遍历所有屏幕;物理像素需用Scale换算;支持ScreenCountChanged等事件监听热插拔与DPI变化。

在 Avalonia 中获取屏幕分辨率和屏幕信息,主要通过 Screen 类和 Screens 静态集合实现。它不依赖 Win32 或平台特定 API,而是跨平台统一抽象(支持 Windows、macOS、Linux),但底层行为会因平台而异。

获取主屏幕分辨率

最常用的是获取当前主显示器的尺寸(通常为应用所在屏幕):

  • 使用 Avalonia.Controls.TopLevel.GetTopLevel(this) 获取当前窗口所在的顶层控件
  • 调用 .Screens.ScreenFromPoint(...) 或直接访问 .Screens.Primary

示例代码:

var topLevel = TopLevel.GetTopLevel(this);
if (topLevel?.Screens is { } screens)
{
    var primary = screens.Primary;
    var dpi = primary.Dpi; // DPI 缩放比例(如 96, 144, 192)
    var bounds = primary.Bounds; // 设备无关像素(DIP)坐标和大小
    var workingArea = primary.WorkingArea; // 排除任务栏/菜单栏后的可用区域
    var resolution = new PixelSize(bounds.Width, bounds.Height); // DIP 尺寸
}

获取所有屏幕列表及详细信息

适用于多屏场景,比如让窗口居中到某块屏、或动态适配不同分辨率屏幕:

  • Screens.All 返回所有已连接屏幕的只读集合
  • 每个 Screen 包含 Bounds(总区域)、WorkingArea(可用区域)、DpiScale(缩放因子,如 1.5)、Id(平台相关标识)
  • BoundsWorkingArea 单位是 DIP(设备无关像素),不是物理像素

示例:

foreach (var screen in Screens.All)
{
    Console.WriteLine($"ID: {screen.Id}");
    Console.WriteLine($"Bounds: {screen.Bounds}");
    Console.WriteLine($"WorkingArea: {screen.WorkingArea}");
    Console.WriteLine($"DPI: {screen.Dpi}, Scale: {screen.Scale}");
}

获取物理像素分辨率(需手动换算)

Avalonia 默认使用 DIP,若需真实像素(如截图、OpenGL 渲染上下文),需结合 Scale 换算:

  • physicalWidth = (int)Math.Round(bounds.Width * screen.Scale)
  • physicalHeight = (int)Math.Round(bounds.Height * screen.Scale)
  • 注意:不同平台 Scale 含义略有差异(如 macOS 使用逻辑缩放,Linux X11 可能为 1.0)

监听屏幕变化(热插拔、DPI 改变)

屏幕列表支持响应式更新,可订阅事件:

  • Screens.ScreenCountChanged:屏幕增减(如插入/拔出显示器)
  • Screens.PropertyChanged:某些平台可能触发 DPI 或布局变更(非所有平台都完全支持)

建议在 OnAttachedToVisualTree 或窗口初始化后订阅,并在销毁时取消订阅。