2010-02-16 26 views
9

He escrito un programa WinForms en C# .Net para hacer clic en un botón programáticamente dentro de un formulario de contraseña.Botón programático clic arroja la excepción 'System.StackOverflowException'

Form1 carga y muestra Form2 como un cuadro de diálogo.

La aplicación se cerrará si DialogResult es otra cosa que DialogResult.OK.

Hasta ahora tener un evento de clic de botón, que se codifica de la siguiente manera:

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(); 
       } 
      } 

utilizo radButton1.PerformClick();, pero ejecutar el programa me da el siguiente mensaje:

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

estoy no está seguro de qué está causando esta excepción.

+0

olvidó añadir, este código está dentro del botón que se está tratando de simular – Crazyd22

+0

Se puede publicar un poco más sobre lo que está tratando de hacer? En esencia, parece que está atacando el problema de la manera incorrecta, de ahí su problema. Podría ser capaz de sugerir una mejor manera si sabemos lo que está tratando de hacer. – Ian

Respuesta

7

Editar No es una suposición. Decirle al botón que haga clic dentro de sí mismo definitivamente está causando un ciclo infinito. Esto hace que el método se llame una y otra vez, llenando la pila y haciendo que se desborde.

Supongo que llamar al PerformClick() hace que el método actual que publicó se vuelva a llamar, lo que causa un bucle de llamada infinito y da como resultado un StackOverflowException.

Para evitar esto, es necesario fijar la lógica en algún lugar de su código para que:

if (txtpass.Text == "1234") 

evalúa a false y el método de clic no se consiga llamar una y otra vez. Probablemente pueda lograr esto configurando txtpass.Text = "" justo antes de hacer que haga clic de nuevo.

+0

Ah veo, alguna idea sobre cómo evitar esto? – Crazyd22

+0

"Probablemente pueda lograr esto configurando txtpass.Text =" "justo antes de hacer que vuelva a hacer clic en sí mismo". Pero entonces arrojará el cuadro de mensaje de "contraseña inválida", entonces, ¿cuál es el punto? –

+0

Voy a intentarlo gracias – Crazyd22

1

Para llamar al controlador de eventos de nuevo desde el interior podría utilizar el siguiente código:

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

     txtpass.Text = "12345"; 

     radButton1.PerformClick(); 

     break; 

    default: 
     case "12345": 
     break; 

} 
+0

Esto es porque necesito configurar el botón de diálogo, pero no quiero hacer esto sin que ellos ingresen la contraseña, pero esto significa que tienen que hacer clic dos veces – Crazyd22

3

Normalmente se llamarían manualmente el caso de que usted está intentando ejecutar.

E.g. si usted tiene un método

button1_Click(object sender, ButtonEventArgs e) 
{ 
} 

allí tendría que llamar al siguiente en el código:

button1_Click(this, new ButtonEventArgs()); 

Creo que tal vez es necesario explicar algo de lógica en el código embargo, ya que no está claro lo que' Estoy tratando de hacer. El StackOverflow probablemente porque está haciendo

PerformClick() -> PerformClick() -> PerformClick() porque su texto "1234" nunca cambia entre llamadas.

+0

Esto también causaría un bucle infinito si se llama desde Button1_Click . –

+0

Andy, sí lo sé, fue solo la primera parte de mi respuesta ... Gracias :) – Ian

+0

Desventajas en cuanto a responder a una publicación en unas pocas etapas ... – Ian

1

¿Está el PerformClick() dentro del evento de clic del botón? Si es así, es ahí donde te equivocas porque estás lanzando tu aplicación a un ciclo infinito.

usuario hace clic en el botón,
.NET corre Haga clic controlador on(),
botón hace clic PerformClick(),
.carreras Net Haga clic) manejador (,
botón hace clic PerformClick(),
.NET corre Haga clic controlador on(),
botón hace clic PerformClick(),

etc.

Es form1 definitivamente llamando ShowDialog() en form2, y no sólo Show()?

En lugar de radButton1.DialogResult, intente configurar this.DialogResult == DialogResult.OK.

El DialogResult propiedad en un botón dice .NET, que DialogResult para asignar a la Form cuando se hace clic en el Button.

+0

Gracias, pero he resuelto el problema – Crazyd22

0

Un desbordamiento de pila ocurre generalmente porque el método se llama a sí mismo indefinidamente, porque cada vez que se invoca un método, se agrega una entrada a la pila hasta el punto en que ya no queda más pila.

Para detener la recursión, quitar la línea radButton1.PerformClick();

Cuestiones relacionadas