Updating to Forms 2.0.0 throws Layout cycle detected. Layout could not complete exception!

HarikrishnanHarikrishnan USMember ✭✭
edited November 2015 in Xamarin.Forms

Updating to Forms 2.0.0 throws Layout cycle detected. Layout could not complete exception in WindowsPhone and WinRT. In Android and iOS, I dont experience any crash, but it makes a strange behavior to my app as there are lot of cyclic layout calls.

My application is basically a grid view that arranges data objects in rows and columns. I have applied Virtualization concept in my application to reuse the rows and columns upon scrolling. This was working fine till the Forms 1.5.1.6471 version. But after updating to 2.0.0 am facing a lot of issues in my application as too many layout calls happens in my application.

Basically my idea is to have a ScrollView which has a Container derived from layout \<view> as content. My container contains a lot of row which is nothing but customized Layout. Each row holds number of cells(Labels) which are derived from ContentView.

I will bind a collection of objects to my application as input, say a List of 100 objects. If the view contains only ten rows then I will take the first 10 objects from the collection and set each object as BindingContext to each row that is loaded in view. So each row will have an object from the collection as BindingContext. So obviously all the labels inside the row will have the same object as binding Context. And I have binded the TextProperty of each label to a property name in the object(BindingContext) to get the text displayed correctly.

Upon scrolling I will just change the BindingContext of the row (which in turn for all labels inside the row) that goes out of view and will manually rearrange that row to the bottom of the view to get the maximum possible performance. This was working fine till 1.5.1.6471. But after updating to version 2.0.0 when I change the BindingContext of the row that goes out of view, an Invalidate measure call occurs from the root view of my application for binding context change in each cell(label) in my row which results in a cyclic layout pass.

On Checking this deeper, I noticed that Xamarin has made an Invalidate Call on TextProperty changed of Label(something like "Xamarin.Forms.InvalidationTrigger trigger = RendererReady" I see in call stack) when its BindingContext is changed. This Invalidate calls makes call to the parent of label and its parent recursively, may be to refresh the text change in view. But in my case this totally breaks my application as there will be 40 to 50 labels in view in my case and for each label the invalidate measure makes a root layout pass resulting in Layout Cycle detected exception.

If this Invalidation is mandatory for any purpose, then, It would be more appropriate if Xamarin could give an option to Skip this Invalidation when BindingContext is changed for a view. I guess we already have two such overrides "ShouldInvalidateOnChildAdded and ShouldInvalidateOnChildRemoved". Like that it will be fine if another override "ShouldInvalidateOnBindingContextChanged" is introducted to skip invalidation when BindingContext is changed for a view. This is just my suggestion.

Any kind of fix for this is much appreciable and is mandatory as currently am damn stuck in running my application with latest forms version. Am totally frustrated because of this as I have no clue what to do to overcome this problem. **Is there any workaround for this? And when I get this fixed permanently. I hope Xamarin can address this issue with "High Priority" and get me this fixed ASAP.

If you need any other details for fixing this am happy to give it. All I need is to get this issue fixed ASAP.

Answers

Sign In or Register to comment.