xamarin/Xamarin.Forms

[Bug] RelativeLayout.Children.Clear crashes when elements are connected to each other

Open

#8,796 opened on Dec 8, 2019

 (2 comments) (0 reactions) (0 assignees)C# (1,926 forks)batch import
a/layoute/5 :clock5:help wantedi/highinactivet/bug :bug:up-for-grabs

Repository metrics

Stars
 (5,644 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Description

RelativeLayout.Children.Clear removes 1 by 1 item firing CollectionChanged on each item removed, instead of using the proper NotifyCollectionChangedAction.Reset.

This causes a RelativeLayout to crash if you added items with constraints relative to each other as it is trying to solve those constraints while removing all items.

Steps to Reproduce

Add items to a RelativeLayout with constraint to the previously added item. Perform Clear on this panel.

Expected Behavior

Items are removed without resolving Constraints along the way.

Actual Behavior

App crashes.

Basic Information

  • Version with issue: latest
  • Last known good version: Never

Reproduction Link

var button = new Button { Text = "Hello GitHub" };
button.Clicked += (sender, e) => relativeLayout.Children.Clear();
relativeLayout.Children.Add(button, widthConstraint: Constraint.RelativeToParent(r => r.Width));
for (var i = 0; i < 20; i++)
{
    relativeLayout.Children.Add(new Button(),
        yConstraint: Constraint.RelativeToView(relativeLayout.Children.Last(), (r, v) => v.Y));
}

I navigated through Xamarin.Forms and found the Issue should originate from ObservableWrapper.Clear.

I didn't manage to build Xamarin.Forms, but I assume something like this would fix the issues: https://github.com/Illedan/Xamarin.Forms/commit/e02a67050477a774ae2110a7118b8c9fbea15532

Another option would be to remove the item.Owned flag in one loop and perform _list.Clear afterwards.

Screenshot

Workaround

A workaround for this issue is to remove the items manually in known correct order.

Contributor guide