问题描述
使用Avalonia UI开发跨平台桌面应用,设置了窗口启动位置,如下
WindowStartupLocation="CenterScreen"
程序发布后,在Windows上运行正常,启动位置为屏幕中央,但是一些Linux中启动位置不对。
- Avalonia版本:0.10.8
- 测试Linux系统:Deepin
解决方式
使用编码方式,动态计算屏幕中央位置,放置窗体:
- 监听窗体
IsVisible
属性
- 在首次出现时,进行计算
具体代码如下
监听属性代码:
private bool _done;
public MainWindow()
{
InitializeComponent();
var iv = this.GetObservable(Window.IsVisibleProperty);
iv.Subscribe(async value =>
{
await Task.Delay(1);
if (value && !_done)
{
_done = true;
SetWindowStartupLocationWorkaround();
}
});
}
设置窗体位置代码如下:
private void SetWindowStartupLocationWorkaround()
{
if (OperatingSystem.IsWindows())
{
// Not needed for Windows
return;
}
var scale = PlatformImpl?.DesktopScaling ?? 1.0;
var powner = Owner?.PlatformImpl;
if (powner != null)
{
scale = powner.DesktopScaling;
}
var rect = new PixelRect(PixelPoint.Origin, PixelSize.FromSize(ClientSize, scale));
if (WindowStartupLocation == WindowStartupLocation.CenterScreen)
{
var screen = Screens.ScreenFromPoint(powner?.Position ?? Position);
if (screen == null)
{
return;
}
Position = screen.WorkingArea.CenterRect(rect).Position;
}
else
{
if (powner == null || WindowStartupLocation != WindowStartupLocation.CenterOwner)
{
return;
}
Position = new PixelRect(powner.Position, PixelSize.FromSize(powner.ClientSize, scale)).CenterRect(rect)
.Position;
}
}
原因分析
这应该是Avalonia的一个Bug,在Linux启动时 ,窗体位置计算的问题,最新预览版应该已经解决了这个问题,不过目前稳定版,还需要自己手动解决一下。