在 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}"/>
当我创建 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}"/>