StackOverFlow when parameters not in the right order

Feb 4, 2011 at 11:32 AM

Hi,

I stumbled on this very nasty issue that wasted 1 hour of my life. Here are 2 snippets of code.

Snippet 1:

 

        <Layout_Toolkit:TransitioningContentControl Grid.Row="1" cal:View.Context="{Binding Path=State, Mode=TwoWay}" cal:View.Model="{Binding}"                                                        
					HorizontalContentAlignment="Stretch"  
                                        VerticalContentAlignment="Stretch" />

Snippet2:

        <Layout_Toolkit:TransitioningContentControl Grid.Row="1" cal:View.Model="{Binding}" cal:View.Context="{Binding Path=State, Mode=TwoWay}"
					HorizontalContentAlignment="Stretch"  
                                        VerticalContentAlignment="Stretch" />

Anyone will expect this to be equivalent. But in real live (or real applications) Snippet2 will result in a stackoverflow exception. "Ain't that a bitch" (quote from Aerosmith)

Regards,

PS. Investing the caliburn code to propose a solution. Will be back later with it.

Coordinator
Feb 4, 2011 at 1:33 PM

Let me know if you find a reasonable solution, or at least a way to throw a meaningful exception that will tell people hot to fix the issue. Sorry about the lost time ;(

Feb 4, 2011 at 1:37 PM
Edited Feb 4, 2011 at 1:39 PM

I've happened to notice this surprising asymmetrical behavior even in core WPF controls.
Yet, I agree that the order of attributes should NOT be important.
As far I can remember, CM has some "protections" against the inversion of View.Context and View.Model order in Xaml; apparently is not enough.

Maybe the issue is related to the TwoWay binding mode, which is quite unusual.
Just out of curiosity, why do you need to bind in both way?

Thank you for pointing it out.

Feb 5, 2011 at 4:40 PM

Hi,

Spend some time today to investigate the cause of the issue, made a unit tests to prove the issue and found a possible fix (but because of the lack of other unit tests I am not sure if I broke something).

On the latest source code (dated the same as this post) The class responsable for the issue is (of course) public static class View

In OnModelChanged there is line 129 ViewModelBinder.Bind(args.NewValue, view, context); that leads to stack overflow. The function has if (args.OldValue == args.NewValue) to guard for this thinks but unfortunately the value does not get set.

So the quick fix (passed the test) was to swith lines 129 and 130, insteed of:

                ViewModelBinder.Bind(args.NewValue, view, context);|
                SetContentProperty(targetLocation, view);

I have:

                SetContentProperty(targetLocation, view);
                ViewModelBinder.Bind(args.NewValue, view, context);|

That seems to do the trick, let me know what you think about it.

Regards,

Feb 14, 2011 at 2:17 PM

I hit this issue today, I have the latest source and it still got an SO when the context was after the binding. (snippet 1).

 

Coordinator
Feb 14, 2011 at 9:17 PM

Can you send me a simple solution that reproduces the problem? Send to robertheisenberg at hotmail dot com

Feb 15, 2011 at 9:55 AM
Hi Rob,

Here is a sample.

Extracted the 2 projects from the solution. Simply create a new solution and add the references to caliburn.
MainPageView.xaml has the issue.

Regards,

On 2/15/2011 12:17 AM, EisenbergEffect wrote:

From: EisenbergEffect

Can you send me a simple solution that reproduces the problem? Send to robertheisenberg at hotmail dot com


--

MTCS, .net 2.0, .net 3.5, WPF
Calinoiu Alexandru Nicolae (software craftsman)

tel: +40745 857479
skype: calinoiu.alexandru