如何消除在DataContext InitializeComponent中的StackOverflow异常?

3
我是新手想尝试一些WPF C#的示例应用程序,问题在于当我在XAML中提到DataContext时,InitializeComponent被递归调用并显示如下错误:

System.StackOverflowException' 在 mscorlib.dll 中发生

这是我的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个回答

5

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

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

了解有关DataContext属性的更多信息,请参阅codeproject 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} >

定位器将作为Resources.xaml中的资源。

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

你可以在geekchamp中获取定位器类和有关MVVM模式的更多详细信息。 使用来自MVVM-Light的简单ViewModelLocator

我刚遇到了与Arpitha相同的问题,并且在处理您的第一条语句时遇到了麻烦。我阅读了MSDN并认为我不需要提供DataContext,但是如果没有它,我无法将集合分配为我的DataGrid的ItemsSource。只有在<DataGrid.DataContext><Window.DataContext>中添加<local:MainWindow />或者在代码后台使用myDataGrid.DataContext = this;才能看到我的集合。前者失效,后者有效。为什么? - Hydronium
谢谢。我在XAML中删除了DataContext,问题解决了。 - AmirHossein Rezaei

2
DataContext属性的描述如下:
直接嵌入的对象,用作父元素内任何绑定的数据上下文。通常,此对象是Binding或另一个BindingBase派生类。或者,可以将任何CLR对象类型的原始数据放置在此处,稍后定义实际的绑定。
在您的XAML中,主窗口的DataContext是...您的主窗口。因此,创建了另一个主窗口的实例。它具有类型为...您的主窗口的DataContext。
因此,创建了另一个主窗口的实例。它具有类型为...您的主窗口的DataContext。
因此,创建了另一个主窗口的实例。它具有类型为...您的主窗口的DataContext。
因此,创建了另一个主窗口的实例。它具有类型为...您的主窗口的DataContext。
所以...
;)
将DataContext设置为包含要绑定窗口的数据的对象,而不是窗口本身。
希望这能帮到您。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接