Tuesday, May 11, 2010

Another Strange Silverlight Error: “Layout cycle detected. Layout could not complete”

Wow! Is this one ever frustrating! So here’s the situation:

I’ve got a datagrid which uses RowGroups. Everything is working just fine until I get a request from the product owner to hide/show several of the columns on that datagrid by clicking a button. I figured “This isn’t going to be too bad. I’ve done this before with other datagrids. Great, I’ll have it done in 10 minutes.” WRONG! To my surprise, I wrote some code very similar to what I’ve done in the past, but I started seeing this funky error “Layout cycle detected. Layout could not complete”. Because this is a Silverlight error, I did not get any other helpful information. Thanks so much Silverlight. Well, I can’t tell you that I completely understand the internals of Silverlight and what is causing this issue, but I do know that it has something to do with looping inside the the UpdateLayout method is executing for the datagrid. It seems to be getting stuck in an infinite loop. After a lot of searching and trying out different things, I came up with a workaround. If you are experiencing this problem, try removing the datagrid from its parent prior to making the change (in my case adding/removing columns) and then add the datagrid back to it’s parent’s Children collection immediately after you make the change.

This solved it for me. Here is a snippet:

            if (show == true)
{
_clmOne.Visibility = Visibility.Visible;
_clmTwo.Visibility = Visibility.Visible;
_clmThree.Visibility = Visibility.Visible;
}
else
{
//Hack:Need to remove the grid prior to adding columns to avoid Exception.
this.LayoutRoot.Children.Remove(myDataGrid);
_clmOne.Visibility = Visibility.Collapsed;
_clmTwo.Visibility = Visibility.Collapsed;
_clmThree.Visibility = Visibility.Collapsed;
this.LayoutRoot.Children.Add(myDataGrid);
}


I hope this helps you guys out. Happy Silverlighting!