Система.Исключение StackOverflowException при запуске приложения

#c# #.net #forms #winforms

Вопрос:

Когда я запускаю свое приложение, оно выдает мне ошибку » Тест Form1 = новая форма 1();» в моем классе. Вот мой код. Я хочу использовать метки из своей формы, поэтому я использовал «тест form1».

Я создал класс, чтобы я мог вызывать из него свои методы в своей основной форме, так как мне нужно кодировать свое приложение с помощью классов. Когда я запустил приложение в первый раз, оно сработало, но затем, после повторной попытки, оно больше не работало.

Основная форма:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;  namespace Tester {  public partial class Form1 : Form  {  Zombie zombie = new Zombie();  int levens = 3;      public Form1()  {  InitializeComponent();      test1.Text = "Levens: "   ""   levens;    }   private void Form1_Load(object sender, EventArgs e)  {   }   public void Zombie()  {   foreach (Control control in Controls)  {  PictureBox pic = control as PictureBox;  if (pic != null)  {  pic.Top  = 1;  if (pic.Top gt; 600 amp;amp; pic.Visible == true)  {   pic.Top = 0;  test1.Text = $"Levens: {--levens}";  }  else if (pic.Top gt; 600 amp;amp; pic.Visible == false)  {  pic.Visible = true;  pic.Top = 0;  }  }  }  }  private void timer1_Tick(object sender, EventArgs e)  {  zombie.MakeZombie(5, this);  }  } }    

Класс:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;  namespace Tester {  class Zombie  {  Random random = new Random();  Form1 Test = new Form1();    private int score = 0;    public void MakeZombie(int aantal, Form formInstance)  {   for (int i = 0; i lt; aantal; i  )  {  PictureBox picture = new PictureBox();  picture.Image = Properties.Resources.ZombieDik;  picture.Size = new Size(200, 200);  picture.Location = new Point(random.Next(1500), 0);  picture.SizeMode = PictureBoxSizeMode.Zoom;  picture.Click  = zombie_Click;  picture.BackColor = Color.Transparent;  formInstance.Controls.Add(picture);  }  }  void zombie_Click(object sender, EventArgs e)  {  PictureBox pic = sender as PictureBox;  pic.Visible = false;  score  ;  Test.label2.Text = $"Score: {score}";  Test.Controls.Remove(pic);  pic.Dispose();  }  } }    

Комментарии:

1. Да, это имеет смысл — ваше приложение создает Form1 при запуске, форма затем создает экземпляр Zombie класса, который, в свою очередь, создает новый Form1 и так далее. Это происходит до тех пор, пока не останется места в стеке и вы не получите переполнение стека.

2. Распространенная ошибка: для доступа к основной форме вам нужна ссылка на нее , а не на новый экземпляр . Создайте конструктор зомби, в котором вы передадите ссылку на Form1..! Только тогда любой зомби будет удален из основной формы..

3. Метод MakeZombie получает экземпляр формы, в которую вы хотите добавить поле с картинками. Просто сохраните этот экземпляр в тесте внутренней переменной и не создавайте другой экземпляр Form1, потому что он запустит бесконечный цикл, который убьет приложение.

4. Кроме того, не уверен, что это отличная идея-удалить и уничтожить элемент управления в том же событии щелчка, вызванном элементом управления, который вы хотите уничтожить. Вероятно, сначала спрячьте его, а затем уничтожьте скрытые коробки с картинками в событии таймера

5. Пожалуйста, проясните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы выделить именно то, что вам нужно. Поскольку это написано в настоящее время, трудно точно сказать, о чем вы просите.

Ответ №1:

В zombie_Click() вы можете получить ссылку на форму от самого отправителя:

 void zombie_Click(object sender, EventArgs e) {  PictureBox pic = sender as PictureBox;   Form1 f1 = pic.FindForm() as Form1;  score  ;  f1.label2.Text = $"Score: {score}";  pic.Dispose(); }