绑定时 InitializeComponent 引发 StackOverflow 异常

mat*_*lat 3 c# data-binding wpf xaml

试图理解数据绑定,这完全看起来像是一个菜鸟错误,但我不知道为什么会发生这种情况。

CS

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

        public MainWindow()
        {
            InitializeComponent();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

调试器指向带有 StackOverflowException 的方法InitializeComponent()调用MainWindow()

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

Roh*_*ats 7

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

<local:MainWindow x:Key="classMainWindow"/>
Run Code Online (Sandbox Code Playgroud)

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


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

<Label Content="{Binding Path=foobar, RelativeSource={RelativeSource FindAncestor, 
                                                            AncestorType=Window}}"/>
Run Code Online (Sandbox Code Playgroud)

或者

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

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}">
  ....
  <Label Content="{Binding foobar}"/>
Run Code Online (Sandbox Code Playgroud)

或者

在窗口上设置 x:Name 并使用 ElementName 进行绑定。

<Window x:Name="myWindow">
   .....
   <Label Content="{Binding foobar, ElementName=myWindow}" />
Run Code Online (Sandbox Code Playgroud)