summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs41
-rw-r--r--Xamarin.Forms.Core/RelativeLayout.cs62
-rw-r--r--docs/Xamarin.Forms.Core/Xamarin.Forms/RelativeLayout.xml84
3 files changed, 179 insertions, 8 deletions
diff --git a/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs b/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs
index 96b3dfc8..fdbcdfc0 100644
--- a/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs
+++ b/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs
@@ -75,6 +75,47 @@ namespace Xamarin.Forms.Core.UnitTests
}
[Test]
+ public void LayoutIsUpdatedWhenConstraintsChange()
+ {
+ var relativeLayout = new RelativeLayout
+ {
+ Platform = new UnitPlatform(),
+ IsPlatformEnabled = true
+ };
+
+ var child = new View
+ {
+ IsPlatformEnabled = true
+ };
+
+ relativeLayout.Children.Add(child,
+ Constraint.Constant(30),
+ Constraint.Constant(20),
+ Constraint.RelativeToParent(parent => parent.Height / 2),
+ Constraint.RelativeToParent(parent => parent.Height / 4));
+
+ relativeLayout.Layout(new Rectangle(0, 0, 100, 100));
+
+ Assert.AreEqual(new Rectangle(30, 20, 50, 25), child.Bounds);
+
+ RelativeLayout.SetXConstraint(child, Constraint.Constant(40));
+
+ Assert.AreEqual(new Rectangle(40, 20, 50, 25), child.Bounds);
+
+ RelativeLayout.SetYConstraint(child, Constraint.Constant(10));
+
+ Assert.AreEqual(new Rectangle(40, 10, 50, 25), child.Bounds);
+
+ RelativeLayout.SetWidthConstraint(child, Constraint.RelativeToParent(parent => parent.Height / 4));
+
+ Assert.AreEqual(new Rectangle(40, 10, 25, 25), child.Bounds);
+
+ RelativeLayout.SetHeightConstraint(child, Constraint.RelativeToParent(parent => parent.Height / 2));
+
+ Assert.AreEqual(new Rectangle(40, 10, 25, 50), child.Bounds);
+ }
+
+ [Test]
public void SimpleExpressionLayout ()
{
var relativeLayout = new RelativeLayout {
diff --git a/Xamarin.Forms.Core/RelativeLayout.cs b/Xamarin.Forms.Core/RelativeLayout.cs
index b3a1b615..2b835013 100644
--- a/Xamarin.Forms.Core/RelativeLayout.cs
+++ b/Xamarin.Forms.Core/RelativeLayout.cs
@@ -8,13 +8,13 @@ namespace Xamarin.Forms
{
public class RelativeLayout : Layout<View>
{
- public static readonly BindableProperty XConstraintProperty = BindableProperty.CreateAttached("XConstraint", typeof(Constraint), typeof(RelativeLayout), null);
+ public static readonly BindableProperty XConstraintProperty = BindableProperty.CreateAttached("XConstraint", typeof(Constraint), typeof(RelativeLayout), null, propertyChanged: ConstraintChanged);
- public static readonly BindableProperty YConstraintProperty = BindableProperty.CreateAttached("YConstraint", typeof(Constraint), typeof(RelativeLayout), null);
+ public static readonly BindableProperty YConstraintProperty = BindableProperty.CreateAttached("YConstraint", typeof(Constraint), typeof(RelativeLayout), null, propertyChanged: ConstraintChanged);
- public static readonly BindableProperty WidthConstraintProperty = BindableProperty.CreateAttached("WidthConstraint", typeof(Constraint), typeof(RelativeLayout), null);
+ public static readonly BindableProperty WidthConstraintProperty = BindableProperty.CreateAttached("WidthConstraint", typeof(Constraint), typeof(RelativeLayout), null, propertyChanged: ConstraintChanged);
- public static readonly BindableProperty HeightConstraintProperty = BindableProperty.CreateAttached("HeightConstraint", typeof(Constraint), typeof(RelativeLayout), null);
+ public static readonly BindableProperty HeightConstraintProperty = BindableProperty.CreateAttached("HeightConstraint", typeof(Constraint), typeof(RelativeLayout), null, propertyChanged: ConstraintChanged);
public static readonly BindableProperty BoundsConstraintProperty = BindableProperty.CreateAttached("BoundsConstraint", typeof(BoundsConstraint), typeof(RelativeLayout), null);
@@ -72,6 +72,25 @@ namespace Xamarin.Forms
}
}
+ static void ConstraintChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ View view = bindable as View;
+
+ (view?.Parent as RelativeLayout)?.UpdateBoundsConstraint(view);
+ }
+
+ void UpdateBoundsConstraint(View view)
+ {
+ if (GetBoundsConstraint(view) == null)
+ return; // Bounds constraint hasn't been calculated yet, no need to update just yet
+
+ CreateBoundsFromConstraints(view, GetXConstraint(view), GetYConstraint(view), GetWidthConstraint(view), GetHeightConstraint(view));
+
+ _childrenInSolveOrder = null; // New constraints may have impact on solve order
+
+ InvalidateLayout();
+ }
+
public static BoundsConstraint GetBoundsConstraint(BindableObject bindable)
{
return (BoundsConstraint)bindable.GetValue(BoundsConstraintProperty);
@@ -102,6 +121,26 @@ namespace Xamarin.Forms
bindable.SetValue(BoundsConstraintProperty, value);
}
+ public static void SetHeightConstraint(BindableObject bindable, Constraint value)
+ {
+ bindable.SetValue(HeightConstraintProperty, value);
+ }
+
+ public static void SetWidthConstraint(BindableObject bindable, Constraint value)
+ {
+ bindable.SetValue(WidthConstraintProperty, value);
+ }
+
+ public static void SetXConstraint(BindableObject bindable, Constraint value)
+ {
+ bindable.SetValue(XConstraintProperty, value);
+ }
+
+ public static void SetYConstraint(BindableObject bindable, Constraint value)
+ {
+ bindable.SetValue(YConstraintProperty, value);
+ }
+
protected override void LayoutChildren(double x, double y, double width, double height)
{
foreach (View child in ChildrenInSolveOrder)
@@ -248,13 +287,13 @@ namespace Xamarin.Forms
static Rectangle SolveView(View view)
{
BoundsConstraint boundsConstraint = GetBoundsConstraint(view);
- var result = new Rectangle();
if (boundsConstraint == null)
{
throw new Exception("BoundsConstraint should not be null at this point");
}
- result = boundsConstraint.Compute();
+
+ var result = boundsConstraint.Compute();
return result;
}
@@ -280,7 +319,7 @@ namespace Xamarin.Forms
public void Add(View view, Expression<Func<Rectangle>> bounds)
{
if (bounds == null)
- throw new ArgumentNullException("bounds");
+ throw new ArgumentNullException(nameof(bounds));
SetBoundsConstraint(view, BoundsConstraint.FromExpression(bounds));
base.Add(view);
@@ -308,7 +347,14 @@ namespace Xamarin.Forms
public void Add(View view, Constraint xConstraint = null, Constraint yConstraint = null, Constraint widthConstraint = null, Constraint heightConstraint = null)
{
- Parent.CreateBoundsFromConstraints(view, xConstraint, yConstraint, widthConstraint, heightConstraint);
+ view.BatchBegin();
+
+ RelativeLayout.SetXConstraint(view, xConstraint);
+ RelativeLayout.SetYConstraint(view, yConstraint);
+ RelativeLayout.SetWidthConstraint(view, widthConstraint);
+ RelativeLayout.SetHeightConstraint(view, heightConstraint);
+
+ view.BatchCommit();
base.Add(view);
}
diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms/RelativeLayout.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms/RelativeLayout.xml
index 8d1082e9..6a8c498b 100644
--- a/docs/Xamarin.Forms.Core/Xamarin.Forms/RelativeLayout.xml
+++ b/docs/Xamarin.Forms.Core/Xamarin.Forms/RelativeLayout.xml
@@ -446,6 +446,90 @@ public class RelativeLayoutExample : ContentPage
<remarks>To be added.</remarks>
</Docs>
</Member>
+ <Member MemberName="SetHeightConstraint">
+ <MemberSignature Language="C#" Value="public static void SetHeightConstraint (Xamarin.Forms.BindableObject bindable, Xamarin.Forms.Constraint value);" />
+ <MemberSignature Language="ILAsm" Value=".method public static hidebysig void SetHeightConstraint(class Xamarin.Forms.BindableObject bindable, class Xamarin.Forms.Constraint value) cil managed" />
+ <MemberType>Method</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>System.Void</ReturnType>
+ </ReturnValue>
+ <Parameters>
+ <Parameter Name="bindable" Type="Xamarin.Forms.BindableObject" />
+ <Parameter Name="value" Type="Xamarin.Forms.Constraint" />
+ </Parameters>
+ <Docs>
+ <param name="bindable">The <see cref="T:Xamarin.Forms.BindableObject" /> to which the constraint will be applied.</param>
+ <param name="value">The <see cref="T:Xamarin.Forms.Constraint" /> on the height of the <paramref name="bindable" />.</param>
+ <summary>Sets <paramref name="value" /> as a constraint on the height of the <paramref name="bindable" />.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="SetWidthConstraint">
+ <MemberSignature Language="C#" Value="public static void SetWidthConstraint (Xamarin.Forms.BindableObject bindable, Xamarin.Forms.Constraint value);" />
+ <MemberSignature Language="ILAsm" Value=".method public static hidebysig void SetWidthConstraint(class Xamarin.Forms.BindableObject bindable, class Xamarin.Forms.Constraint value) cil managed" />
+ <MemberType>Method</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>System.Void</ReturnType>
+ </ReturnValue>
+ <Parameters>
+ <Parameter Name="bindable" Type="Xamarin.Forms.BindableObject" />
+ <Parameter Name="value" Type="Xamarin.Forms.Constraint" />
+ </Parameters>
+ <Docs>
+ <param name="bindable">The <see cref="T:Xamarin.Forms.BindableObject" /> to which the constraint will be applied.</param>
+ <param name="value">The <see cref="T:Xamarin.Forms.Constraint" /> on the width of the <paramref name="bindable" />.</param>
+ <summary>Sets <paramref name="value" /> as a constraint on the width of the <paramref name="bindable" />.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="SetXConstraint">
+ <MemberSignature Language="C#" Value="public static void SetXConstraint (Xamarin.Forms.BindableObject bindable, Xamarin.Forms.Constraint value);" />
+ <MemberSignature Language="ILAsm" Value=".method public static hidebysig void SetXConstraint(class Xamarin.Forms.BindableObject bindable, class Xamarin.Forms.Constraint value) cil managed" />
+ <MemberType>Method</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>System.Void</ReturnType>
+ </ReturnValue>
+ <Parameters>
+ <Parameter Name="bindable" Type="Xamarin.Forms.BindableObject" />
+ <Parameter Name="value" Type="Xamarin.Forms.Constraint" />
+ </Parameters>
+ <Docs>
+ <param name="bindable">The <see cref="T:Xamarin.Forms.BindableObject" /> to which the constraint will be applied.</param>
+ <param name="value">The <see cref="T:Xamarin.Forms.Constraint" /> on the X position of the <paramref name="bindable" />.</param>
+ <summary>Sets <paramref name="value" /> as a constraint on the X position of the <paramref name="bindable" />.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="SetYConstraint">
+ <MemberSignature Language="C#" Value="public static void SetYConstraint (Xamarin.Forms.BindableObject bindable, Xamarin.Forms.Constraint value);" />
+ <MemberSignature Language="ILAsm" Value=".method public static hidebysig void SetYConstraint(class Xamarin.Forms.BindableObject bindable, class Xamarin.Forms.Constraint value) cil managed" />
+ <MemberType>Method</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>System.Void</ReturnType>
+ </ReturnValue>
+ <Parameters>
+ <Parameter Name="bindable" Type="Xamarin.Forms.BindableObject" />
+ <Parameter Name="value" Type="Xamarin.Forms.Constraint" />
+ </Parameters>
+ <Docs>
+ <param name="bindable">The <see cref="T:Xamarin.Forms.BindableObject" /> to which the constraint will be applied.</param>
+ <param name="value">The <see cref="T:Xamarin.Forms.Constraint" /> on the Y position of the <paramref name="bindable" />.</param>
+ <summary>Sets <paramref name="value" /> as a constraint on the Y position of the <paramref name="bindable" />.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
<Member MemberName="WidthConstraintProperty">
<MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty WidthConstraintProperty;" />
<MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty WidthConstraintProperty" />