Xamarin.Forms: Change RelativeLayout constraints afterwards

Viewed 10683

Is it possible to change the constraints of a RelativeLayout after they have been set one time?

In the documentation I see methods like GetBoundsConstraint(BindableObject), but I think you can only use them if you have a XAML file. For now I'm trying to do this in code. I get null if I try

RelativeLayout.GetBoundsConstraint(this.label);

The only way I found out is to remove the children from the layout and add it with the new constraints again.

Example:

public class TestPage : ContentPage
{
    private RelativeLayout relativeLayout;
    private BoxView view;
    private bool moreWidth = false;

    public TestPage()
    {
        this.view = new BoxView
        {
            BackgroundColor = Color.Yellow,
        };

        Button button = new Button
        {
            Text = "change",
            TextColor = Color.Black,
        };

        button.Clicked += Button_Clicked;

        this.relativeLayout = new RelativeLayout();

        this.relativeLayout.Children.Add(this.view,
            Constraint.Constant(0),
            Constraint.Constant(0),
            Constraint.Constant(80),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height;
            }));

        this.relativeLayout.Children.Add(button,
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width / 2;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height / 2;
            }));

        this.Content = this.relativeLayout;
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        double width = 0;
        if(this.moreWidth)
        {
            width = 120;
        }
        else
        {
            width = 80;
        }
        var c= BoundsConstraint.FromExpression((Expression<Func<Rectangle>>)(() => new Rectangle(0, 0, width, this.Content.Height)), new View[0]);
        RelativeLayout.SetBoundsConstraint(this.view, c);
        this.relativeLayout.ForceLayout();
        this.moreWidth = !this.moreWidth;
    }
}
3 Answers

Yes. This possible. Layout code:

<StackLayout RelativeLayout.XConstraint="{Binding XConstaint}" ...>

VM code:

public Constraint XConstaint
{
  get => _xConstaint;
  set { SetFieldValue(ref _xConstaint, value, nameof(XConstaint)); }
}

public override void OnAppearing()
{
  base.OnAppearing();
  XConstaint = Constraint.RelativeToParent((parent) => { return parent.Width - 128; });
}
Related