在 WPF MainWindow 中实例化 class 时出现堆栈溢出?

I get stack overflow when instantiate a class inside WPF MainWindow?

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

这是我的习惯 class (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
        }
    }
}

这是主窗口:

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 Whosebug exception...
            Class2 cl2 = new Class2(); // instance of class2
            cl2.lbxm();// call the method
        }

    }
}

当您创建 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 Whosebug exception...
    Class2 cl2 = new Class2(); // instance of class2
    ...
}

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

如果您需要 Class2 来更新 MainWindow 中的对象(根据您的用例,这可能不是解决此问题的最佳方法),我会将控制权传递给 class 而不是给 class 一个对其父项的引用。像这样的东西会起作用:

//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.

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

将您的代码缩减为:

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}"/>