matt-pielat
matt-pielat

Reputation: 1799

InitializeComponent fires StackOverflow Exception when binding

Trying to understand data binding and this totally seems like a rookie mistake but I have no idea why it's happening.

CS

namespace MuhProgram
{
    public partial class MainWindow : Window
    {
        public string foobar
        {
            get { return "loremipsum"; }
        }

        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

XAML:

<Window x:Class="MuhProgram.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MuhProgram"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
         <local:MainWindow x:Key="classMainWindow"/>
    </Window.Resources>

    <Grid>
        <Label Content="{Binding Source={StaticResource classMainWindow}, Path=foobar}"></Label>
    </Grid>
</Window>

Debugger points at InitializeComponent() call in MainWindow() method with StackOverflowException.

I also tried setting DataContext attribute to "{StaticResource classMainWindow}" in the grid but the effect is the same.

Upvotes: 3

Views: 2345

Answers (1)

Rohit Vats
Rohit Vats

Reputation: 81283

StackOverflow exception is raised because you are recursively creating an instance of MainWindow at this line

<local:MainWindow x:Key="classMainWindow"/>

When InitializeComponent() gets called, it will initialize the XAML and load it from compiled BAML. While loading it found Label Content needs another instance of MainWindow to bind it's Content DP. Hence, it will create MainWindow recursively until it crashes with SO exception.


You don't need to declare another instance of MainWindow. Bind Label to parent instance like this:

<Label Content="{Binding Path=foobar, RelativeSource={RelativeSource FindAncestor, 
                                                            AncestorType=Window}}"/>

OR

Either set DataContext to itself and let Label inherit it from parent window.

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}">
  ....
  <Label Content="{Binding foobar}"/>

OR

Set x:Name on window and bind using ElementName.

<Window x:Name="myWindow">
   .....
   <Label Content="{Binding foobar, ElementName=myWindow}" />

Upvotes: 7

Related Questions