绑定时,InitializeComponent触发StackOverflow异常

时间:2014-10-03 08:07:01

标签: c# wpf xaml data-binding

试图理解数据绑定,这似乎是一个新手的错误,但我不知道它为什么会发生。

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>

调试器指向InitializeComponent()使用StackOverflowException调用MainWindow()方法。

我还尝试在网格中将DataContext属性设置为"{StaticResource classMainWindow}",但效果相同。

1 个答案:

答案 0 :(得分:4)

引发StackOverflow异常,因为您在此行递归创建MainWindow实例

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

当调用InitializeComponent()时,它将初始化XAML并从编译的BAML加载它。在加载时,发现Label Content需要另一个MainWindow实例来绑定它的Content DP。因此,它将以递归方式创建MainWindow,直到它因SO异常而崩溃。


您不需要声明MainWindow的另一个实例。将Label绑定到父实例,如下所示:

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

OR

将DataContext设置为自身,让Label从父窗口继承它。

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

OR

在窗口上设置x:名称并使用ElementName绑定。

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