Я получаю переполнение стека при создании экземпляра класса внутри WPF MainWindow? - PullRequest
0 голосов
/ 16 декабря 2018

Когда я создаю экземпляр класса и вызываю из него метод, я получаю ошибку переполнения стека!На самом деле я хочу предотвратить написание всего моего кода внутри 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 голосов
/ 16 декабря 2018

Сократите свой код до этого:

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 теперь является свойством, к которому вы привязываете свойство ItemsSource ListBox в XAML:

<ListBox ItemsSource="{Binding Names}"/>
0 голосов
/ 16 декабря 2018

Когда вы создаете новый экземпляр 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.

Как я уже упоминал, вероятно, есть более эффективные способы решения этой проблемы, чем передача элемента управления в класс.Это связывает ваши занятия с вашим пользовательским интерфейсом, что в целом нежелательно.Но это в основном то, что вы хотели, чтобы ваш исходный код делал.

...