Программное нажатие кнопки вызывает исключение System.StackOverflowException - PullRequest
9 голосов
/ 16 февраля 2010

Я написал программу WinForms на C # .Net для программного нажатия кнопки в форме пароля.

Form1 загружает и отображает Form2 в виде диалогового окна.

Приложение закроется, если DialogResult отличается от DialogResult.OK.

Пока у меня есть событие нажатия кнопки, которое закодировано следующим образом:

 if (txtpass.Text == "")
            {
                MessageBox.Show("You need to enter a password", "Password", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                txtpass.Focus();
            }
            else
            {
                if (txtpass.Text == "1234")
                {
                    radButton1.DialogResult = DialogResult.OK;
                    radButton1.PerformClick();
                }
                else
                {
                    MessageBox.Show("Password Incorrect", "Password", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtpass.Text = "";
                    txtpass.Focus();
                }
            }

Я использую radButton1.PerformClick();, но при запуске программы выдается следующее сообщение:

An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll

Я не уверен, что вызывает это исключение.

Ответы [ 5 ]

7 голосов
/ 16 февраля 2010

Редактировать Не догадка. Говоря о том, что кнопка щелкает себя изнутри, наиболее определенно вызывает бесконечный цикл. Это заставляет метод вызываться снова и снова, заполняя стек и вызывая его переполнение.

Я предполагаю, что вызов PerformClick() вызывает повторный вызов текущего метода, который вы опубликовали, вызывая бесконечный цикл вызова и приводя к StackOverflowException.

Чтобы предотвратить это, вам нужно исправить логику где-то в вашем коде так:

if (txtpass.Text == "1234")

оценивается как false, и метод click не вызывается снова и снова. Вероятно, этого можно добиться, установив txtpass.Text = "" непосредственно перед тем, как заставить его щелкнуть снова.

3 голосов
/ 16 февраля 2010

Обычно вы вручную вызываете событие, которое пытаетесь запустить.

например. если у вас есть метод

button1_Click(object sender, ButtonEventArgs e)
{
}

Тогда вы бы назвали в своем коде следующее:

button1_Click(this, new ButtonEventArgs());

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

PerformClick () -> PerformClick () -> PerformClick (), потому что ваш текст «1234» никогда не меняется между вызовами.

1 голос
/ 16 февраля 2010

Является ли PerformClick() внутри события нажатия кнопки? Если это так, то вы ошибаетесь, потому что забрасываете свое приложение в бесконечный цикл.

Пользователь нажимает кнопку,
.NET запускает обработчик Click (),
Нажатия кнопок PerformClick(),
.NET запускает обработчик Click (),
Нажатия кнопок PerformClick(),
.NET запускает обработчик Click (),
Нажатия кнопок PerformClick(),

и т.д.

form1 определенно звонит ShowDialog() на form2, а не просто Show()?

Вместо radButton1.DialogResult, попробуйте установить this.DialogResult == DialogResult.OK.

Свойство DialogResult кнопки сообщает .NET, какой DialogResult назначить Form при нажатии Button.

1 голос
/ 16 февраля 2010

Чтобы снова вызвать обработчик событий изнутри, вы можете использовать следующий код:

if (txtpass.Text)
{
    case "1234":
        radButton1.DialogResult = DialogResult.OK;

        txtpass.Text = "12345";

        radButton1.PerformClick();

        break;

    default:
        case "12345":
        break;

}
0 голосов
/ 19 июня 2017

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

Чтобы остановитьрекурсия, убери строку radButton1.PerformClick();

...