2017-10-12 8 views
0

誰かが、次のコードがFormsアプリケーションでOnMeasure()を実行しない理由を知っていますか?私は基本的には広場として表示するには、同じ高さ/幅を有するようにAbsoluteLayoutを強制しようとしている:最終的なサイズを保証するものではありませんOnMeasureコールでAbsoluteLayoutに四角いレイアウトを強制するにはどうすればよいですか?

public class AbsoluteSquareLayout : AbsoluteLayout 
{ 
    protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint) 
    { 
     var size = Math.Min(widthConstraint, heightConstraint); 
     return base.OnMeasure(size, size); 
    } 
} 

答えて

1

オーバーライドサイズの制約 - 親からの最終Layoutパスとしてレイアウトはこの値をオーバーライドします。 XF記事hereがこれについて詳細に話します。

正方形レイアウトを実現するには、これらの制約を考慮して親レイアウトを更新し、レイアウトパスで確実に渡す必要があります。

例えば、AbsoluteLayoutを拡張して、子供のサイズ制限を動的に計算することができます。このカスタムレイアウトは、すべての子をデフォルトで四角形として扱います。特定の子の動作をオーバーライドするには、添付プロパティーSquareLayout.IsSquarefalseと設定することができます。

public class SquareLayout : AbsoluteLayout 
{ 

    public static readonly BindableProperty IsSquareProperty = 
      BindableProperty.CreateAttached("IsSquare", 
              typeof(bool), 
              typeof(SquareLayout), 
              defaultValue: true, 
              defaultBindingMode: BindingMode.OneWay); 

    public static bool GetIsSquare(BindableObject view) 
    { 
     return (bool)view.GetValue(IsSquareProperty); 
    } 

    public static void SetIsSquare(BindableObject view, bool value) 
    { 
     view.SetValue(IsSquareProperty, value); 
    } 

    Dictionary<View, Rectangle> _boundsCache = new Dictionary<View, Rectangle>(); 
    protected override void LayoutChildren(double x, double y, double width, double height) 
    { 
     foreach(var child in Children) 
     { 
      var isSquare = GetIsSquare(child); 
      if(isSquare) 
      { 
       Rectangle bounds; 
       if (!_boundsCache.ContainsKey(child)) 
        _boundsCache[child] = bounds = GetLayoutBounds(child); 
       else 
        bounds = _boundsCache[child]; 

       var absFlags = GetLayoutFlags(child); 

       var widthIsProportional = (absFlags & AbsoluteLayoutFlags.WidthProportional) != 0; 
       var heightIsProportional = (absFlags & AbsoluteLayoutFlags.HeightProportional) != 0; 

       var childWidth = widthIsProportional ? bounds.Width * width : bounds.Width; 
       var childHeight = heightIsProportional ? bounds.Height * height : bounds.Height; 

       var size = Math.Min(childWidth, childHeight); 

       SetLayoutBounds(
        child, 
        new Rectangle(
         bounds.X, 
         bounds.Y, 
         (widthIsProportional ? (size/width) : size), 
         (heightIsProportional ? (size/height) : size) 
        ) 
       ); 
      } 
     } 

     base.LayoutChildren(x, y, width, height); 
    } 
} 

使用例:うわー素晴らしい説明

<local:SquareLayout> 
    <AbsoluteLayout BackgroundColor="Green" 
        AbsoluteLayout.LayoutBounds=".1,.1,1,1" 
        AbsoluteLayout.LayoutFlags="All" /> 

    <AbsoluteLayout BackgroundColor="Blue" 
        AbsoluteLayout.LayoutBounds=".5,.5,.2,.1" 
        AbsoluteLayout.LayoutFlags="All" /> 

    <AbsoluteLayout BackgroundColor="Red" 
        AbsoluteLayout.LayoutBounds=".9,.9,200,200" 
        AbsoluteLayout.LayoutFlags="PositionProportional" /> 

    <AbsoluteLayout BackgroundColor="Yellow" 
        AbsoluteLayout.LayoutBounds="10,20,.3,.3" 
        AbsoluteLayout.LayoutFlags="SizeProportional" /> 

    <AbsoluteLayout BackgroundColor="Silver" 
        local:SquareLayout.IsSquare="false" 
        AbsoluteLayout.LayoutBounds=".9,.9,1,.1" 
        AbsoluteLayout.LayoutFlags="All" /> 
</local:SquareLayout> 

enter image description here enter image description here

+0

!!理解していただきありがとうございます:) – Maximus

関連する問題