You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过XAML/代码实现Avalonia应用90度旋转并解决适配问题?

Avalonia非X11环境下应用90度无拉伸旋转方案

针对你遇到的旋转后拉伸、Flyout未旋转问题,这里提供一个直接有效的实现方案,核心是给整个窗口做视觉旋转,同时适配屏幕尺寸,并统一处理Popup类元素的旋转:

实现步骤

1. 窗口层面设置旋转与尺寸适配

直接在Window上添加RenderTransform实现整体旋转,同时后台代码中交换窗口宽高以匹配旋转后的屏幕比例,避免拉伸:

XAML代码

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="RotateApp.MainWindow"
        Title="RotatedApp"
        RenderTransformOrigin="0.5,0.5">
    <!-- 窗口中心旋转90度 -->
    <Window.RenderTransform>
        <RotateTransform Angle="90"/>
    </Window.RenderTransform>
    
    <!-- 你的主布局内容 -->
    <Grid>
        <Button Content="打开Flyout" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button.Flyout>
                <Flyout>
                    <StackPanel Padding="10">
                        <TextBlock Text="Flyout内容"/>
                        <Button Content="Flyout按钮" Margin="0,5,0,0"/>
                    </StackPanel>
                </Flyout>
            </Button.Flyout>
        </Button>
    </Grid>
</Window>

C#后台代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Platform;

namespace RotateApp;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        AdjustWindowForRotation();
        // 全局监听Popup打开事件,统一处理Flyout旋转
        EventManager.RegisterClassHandler(typeof(Popup), Popup.OpenedEvent, OnPopupOpened);
    }

    private void AdjustWindowForRotation()
    {
        var primaryScreen = Screens.Primary;
        var workArea = primaryScreen.WorkingArea;
        
        // 旋转后交换窗口宽高,匹配屏幕的高/宽
        Width = workArea.Height;
        Height = workArea.Width;
        
        // 让窗口居中显示
        Position = new PixelPoint(
            (workArea.Width - (int)Width) / 2,
            (workArea.Height - (int)Height) / 2
        );
    }

    private void OnPopupOpened(object? sender, RoutedEventArgs e)
    {
        if (sender is not Popup popup || popup.Child == null) return;
        
        // 给Popup设置和窗口一致的旋转
        popup.RenderTransformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative);
        popup.RenderTransform = new RotateTransform(90);
        
        // 修正Popup位置,避免旋转后偏移
        if (popup.PlacementTarget is Control target)
        {
            var targetScreenPos = target.PointToScreen(new Point(0, 0));
            popup.Placement = PlacementMode.Absolute;
            // 旋转后Popup的宽高会交换,所以这里用Child的高/宽计算偏移
            popup.HorizontalOffset = targetScreenPos.X + (target.Bounds.Width / 2) - (popup.Child.Bounds.Height / 2);
            popup.VerticalOffset = targetScreenPos.Y + (target.Bounds.Height / 2) - (popup.Child.Bounds.Width / 2);
        }
    }
}

2. 关键细节说明

  • 避免拉伸:通过交换窗口的宽高为屏幕的高/宽,确保旋转后的窗口尺寸完全适配屏幕,不会出现拉伸变形。
  • Flyout旋转:Flyout本质是通过Popup实现的,不属于主布局的视觉树,所以需要全局监听Popup.Opened事件,给每个弹出的Popup添加相同的旋转变换,并调整位置修正偏移。
  • 非X11兼容性:该方案基于Avalonia内置的RenderTransform,不依赖X11系统特性,在Windows、macOS等非X11环境下均可正常工作。

内容的提问来源于stack exchange,提问作者dwjbosman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:15:30