如何摆脱DataContext InitializeComponent中的StackOverflow异常?

时间:2013-01-04 06:28:49

标签: c# wpf data-binding mvvm datacontext

我是wpf c#的新手,尝试了一些示例应用程序,问题是当我在xaml中提到DataContext时,递归调用InitializeComponent并显示

  mscorlib.dll中出现

System.StackOverflowException'

这是我的XAML标记:

<Window x:Class="Company1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Company1"
    Title="MainWindow" Height="350" Width="525" >
<Window.DataContext>
   <local:MainWindow/>
</Window.DataContext>
  <Grid>
     <GroupBox Margin="5,5,5,5" Background="Beige">
         <Grid>
             <StackPanel>
                <Button Width="80" Height="25" Margin="10,10,10,10" 
                        Content="Employee" Command="{Binding ButtonCommand}"
                        DataContext="{Binding }">
                </Button>
            </StackPanel>
            <DataGrid 
                  Name="myGridView" Margin="5,69,5,5" 
                  Width="Auto" AutoGenerateColumns="True"
                  AlternatingRowBackground="Bisque">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name"
                                        Binding="{Binding Path=EmpName}" 
                                        Width="*" IsReadOnly="True"/>
                    <DataGridTextColumn Header="ID" 
                                        Binding="{Binding Path=EmpId}" 
                                        Width="*" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Place" 
                                        Binding="{Binding Path=Location}" 
                                        Width="*" IsReadOnly="False"/>
                    <DataGridTextColumn Header="Dept" 
                                        Binding="{Binding Path=Department}" 
                                        Width="*" IsReadOnly="True"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </GroupBox>
</Grid>
</Window>

XAML.cs

 private ICommand m_ButtonCommand;
 public ICommand ButtonCommand
 {
     get { return m_ButtonCommand; }
     set { m_ButtonCommand = value; }
 }
 public MainWindow()
 {
     InitializeComponent();
     ButtonCommand = new RelayCommand(new Action<object>(ShowEmployees));
 }

2 个答案:

答案 0 :(得分:3)

如果您使用xaml.cs中的属性,则不需要提供数据上下文,因为它是相同的分部类

当您将数据上下文设置为MainWindow时,它会创建另一个MainWindow实例,并尝试将其数据上下文设置为MainWindow。因此,进入无限循环,给出stackoverflow异常。

详细了解codeproject DataContext in WPF

中的DataContext属性

如果您正在为视图模型使用另一个类,那么您需要通过定位器提供数据上下文

<Window x:Class="Company1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Company1"   
    Title="MainWindow" Height="350" Width="525"
    DataContext={Binding Path=MainWindowViewModel, StaticResource locator} >

和locator将是Resources.xaml中的资源

 <MVVM:MainPageViewModelLocator x:Key="locator" />

您可以在geekchamp中获取定位器类以及有关MVVM模式的更多详细信息Working with a simple ViewModelLocator from MVVM-Light

答案 1 :(得分:0)

DataContext属性描述如下:

直接嵌入的对象,用作父元素中任何绑定的数据上下文。通常,此对象是Binding或另一个BindingBase派生类。或者,可以将此处用于绑定的任何CLR对象类型的原始数据放在此处,稍后定义实际绑定。

在您的XAML中,主窗口的DataContext是....您的主窗口。 所以创建了主窗口的另一个实例。它有一个类型的DataContext ...你的主窗口。

因此创建了另一个主窗口实例。它有一个类型的DataContext ...你的主窗口。

因此创建了另一个主窗口实例。它有一个类型的DataContext ...你的主窗口。

因此创建了另一个主窗口实例。它有一个类型的DataContext ...你的主窗口。

所以......

将DataContext设置为包含要绑定窗口的数据的对象,而不是窗口本身。

希望这有帮助