将 Xamarin.Forms 元素旋转 90 度(横向显示而不旋转整个页面或设备)

Rotate Xamarin.Forms element by 90 degrees (display in landscape without rotating the whole page or device)

页面上只有一个元素,如带有子元素的网格,应旋转 90 度,同时通常与其周围的堆栈布局等对齐。

有一个 Rotation="90" 属性。它有效,但对齐方式似乎是按其原始方向计算的,并且不考虑现在交换的高度和宽度。因此,如果该元素不是正方形,它现在会与其他元素重叠或部分绘制在屏幕之外。这对我来说没有多大意义。怎么做才对?

将元素放入RelativeLayout,可以自由定位元素。

<RelativeLayout>
  <Grid Rotation="90" AnchorX="0" AnchorY="0"
        RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
        RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}"
        RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}">

  </Grid>
</RelativeLayout>

仅仅交换了宽度和高度后,元素位置仍然是错误的,因为它是围绕原来的中心旋转的(AnchorXY默认是0.5)。这可以通过 (Width - Height) / 2 的翻译来解决(参见下面的代码隐藏解决方案),但是我们通过将旋转锚点更改为它的一个角来变得更容易,如上所示。

/// <summary>
/// Rotates an element by 90 or 270 degrees. It is required that you put a RelativeLayout (no parameters needed)
/// around it and call this method on the element (i.e. in onAppearing).
/// </summary>
private void SetLandscape(VisualElement element, bool ccw = false)
{
    element.Rotation = ccw ? 270.0 : 90.0;
    RelativeLayout.SetHeightConstraint(element, Constraint.RelativeToParent(layout => layout.Width));
    RelativeLayout.SetWidthConstraint(element, Constraint.RelativeToParent(layout => layout.Height));
    RelativeLayout.SetYConstraint(element, Constraint.RelativeToParent(layout => (layout.Height - layout.Width) / 2));
    RelativeLayout.SetXConstraint(element, Constraint.RelativeToParent(layout => (layout.Width - layout.Height) / 2));
}

这两种解决方案在运行时更改布局后仍能正常工作。