实例化WPF MainWindow中的类时出现堆栈溢出?

时间:2018-12-16 15:26:21

标签: c# wpf stack-overflow

当我创建一个类的实例并从中调用方法时,出现堆栈溢出错误!实际上,我想防止在MainWindow中编写整个代码,因此需要将它们分成不同的类。

这是我的自定义类(class2):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    class Class2
    {
        private string[] names = { "USA", "Canada", "China", "Peru", "Germany" }; // really simple array
        MainWindow mn = new MainWindow(); // Main window instance

        public void lbxm() // this method shows array element inside a listBox
        {
            ListBox lbx = new ListBox() { Width = 200 };
            for (int i = 0; i < names.Length; i++)
            {
                lbx.Items.Add(names[i]);
            }

            mn.grd.Children.Add(lbx); // place the listBox in Main grid layout
        }
    }
}

这是MainWindow:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {


        public MainWindow()
        {
            InitializeComponent(); // here's the problem, i get stackoverflow exception...
            Class2 cl2 = new Class2(); // instance of class2
            cl2.lbxm();// call the method
        }

    }
}

2 个答案:

答案 0 :(得分:2)

将您的代码精简到此:

class Class2
{
    public string[] Names { get; } = { "USA", "Canada", "China", "Peru", "Germany" };
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new Class2();
    }
}

public string[] Names现在是一个属性,您可以在XAML中将ListBox的ItemsSource属性绑定到该属性:

<ListBox ItemsSource="{Binding Names}"/>

答案 1 :(得分:0)

创建Class2的新实例时,还创建了MainWindow的新实例:

class Class2
{
    private string[] names = { "USA", "Canada", "China", "Peru", "Germany" }; // really simple array
    MainWindow mn = new MainWindow(); // Main window instance <- this is the problem
    ...
}

问题是当Class2创建新的MainWindow时,新MainWindow然后创建新的Class2

public MainWindow()
{
    InitializeComponent(); // here's the problem, i get stackoverflow exception...
    Class2 cl2 = new Class2(); // instance of class2
    ...
}

这个新的Class2然后创建另一个MainWindow,然后重复该循环直到堆栈溢出。即使此代码未创建导致堆栈溢出的循环,该代码仍无法按您希望的方式工作。您在MainWindow中创建的Class2不是您的应用程序创建的主窗口:它是一个全新的MainWindow对象。

如果您需要Class2更新MainWindow中的对象(这可能不是解决此问题的最佳方法,具体取决于您的用例),我会将控件传递给类,而不是给该类提供对其父级的引用。这样的事情会起作用:

//In Class2
public void PopulateListBox(ListBox grd) 
{
    for (int i = 0; i < names.Length; i++)
    {
        grd.Items.Add(names[i]);
    }
}

调用方法:

//In MainWindow
Class2 cl2 = new Class2();
cl2.PopulateListBox(grd); // pass the ListBox where you want the items.

正如我提到的,解决此问题的方法可能比将控件传递给类更好。这会将您的类耦合到您的UI,通常这是不希望的。但这基本上可以完成您希望原始代码执行的操作。