none
Evento KeyPress y KeyDown

    Question

  • Buenas: Estoy intentando añadir la funcionalidad de poder eliminar unos pictureBox en tiempo de ejecución. Al insertar los pictureBox en el panel hago un drag&drog copiando las propiedades del pictureBox, propiedades como Width, Heigh, Padding y Backcolor. Al no copiar la propiedad Name (cosa q no me parece muy útil, ya que todos los pictureBox que añada tendrían la misma) no puedo utilizar la función :

    this.Controls.RemoveByKey("pictureBox1");

    Lo estoy intentando con la función:

    this.Controls.Remove(pictureBox);

    Pero no me funciona.Tengo que decir, que al insertar o al hacer click sobre el pictureBox, este tiene el foco.

    Esta es el método que estoy utilizando:

    public void pictureBox_KeyPress(object sender, KeyPressEventArgs e)
        {
          PictureBox pict = (PictureBox)sender;
    
          if (e.KeyChar == Convert.ToChar(127) | e.KeyChar == Convert.ToChar(8))
          {
            this.Controls.Remove(pict);
          }
        }
    

    Intento que se lance el evento cuando se presione la tecla Supr y la de retroceso, borrar.

     

    La segunda cuestión es intentar mover el pictureBox por el panel, cosa que me iba con el evento KeyUp pero al intentar hacerlo con el evento KeyDown (que me parece mejor) no va.

    public void pictureBox_KeyDown(object sender, KeyEventArgs e)
        {
          PictureBox pict = (PictureBox)sender;
          switch (e.KeyValue)
          {
            case 37: //left arrow
            {
              pict.Left -= 10;
              break;
            }
            case 38: //up arrow
            {
              pict.Top -= 10;
              break;
            }
            case 39: //right arrow
            {
              pict.Left += 10;
              break;
            }
            case 40: //down arrow
            {
              pict.Top += 10;
              break;
            }
          }
        }
    

    Después inserto el manejador.

          pict.KeyDown += new KeyEventHandler(pictureBox_KeyDown);
          pict.KeyPress += new KeyPressEventHandler(pictureBox_KeyPress);
    

    No entiendo porque no funciona, no me da ningún error.

    Aparte de que no funcione....¿Cómo podría hacer para que se moviera el pictureBox continuamente mientras tenga pulsada las teclas de dirección? ¿Con el método Move?

     

    Gracias de antemano

    Sunday, September 05, 2010 11:36 PM

Answers

  • Hola Juan Carlos!, acabo de ver el post de casualidad, ya no me llegan al correo el aviso de que tengo respuestas en los posts. Pues el tema concluyo en que al final no use KeyDown, ni KeyUp, ni KeyPress.

    Algunos no iban como deberian ir, o no capturaban todas las teclas, asi que al final use el método "ProcessCmdKey".

    Es un evento que no entiendo muy bien cómo funciona pero al parecer es parecido al KeyDown o KeyPress.

    Escribí el método de la siguiente forma:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
          if ((keyData != Keys.Up && keyData != Keys.Down && keyData != Keys.Left && keyData != Keys.Right && keyData != Keys.Delete && keyData != Keys.Back))
            return base.ProcessCmdKey(ref msg, keyData);
    
          //Control que actualmente tiene el foco
          if (pictActivo == null)
            return base.ProcessCmdKey(ref msg, keyData);
          else
          {
            switch (keyData)
            {
              case Keys.Up: // up
                if ((pictActivo.Top - 5) > 25)
                {
                  pictActivo.Top -= 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Top = 20;
                break;
              case Keys.Left: // Left
                if ((pictActivo.Left - 5) > 20)
                {
                  pictActivo.Left -= 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Left = 20;
                break;
              case Keys.Right: // right
                if ((pictActivo.Left + pictActivo.Width + 5) < (panelPictogramas.Width - 20))
                {
                  pictActivo.Left += 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Left = panelPictogramas.Width - pictActivo.Width - 20;
                break;
              case Keys.Down: // down
                if ((pictActivo.Top + pictActivo.Height + 5) < (panelPictogramas.Height - 25))
                {
                  pictActivo.Top += 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Top = panelPictogramas.Height - pictActivo.Height - 20;
                break;
              case Keys.Delete:
                ((FormPadre)this.ParentForm).btnBorrar.PerformClick();
                break;
              case Keys.Back:
                ((FormPadre)this.ParentForm).btnBorrar.PerformClick();
                break;
            }
          }
          return base.ProcessCmdKey(ref msg, keyData);
        }
    

    Básicamente, con las teclas de dirección mueve el pictureBox activo, después imprimo las coordenadas del pictureBox y cambio el texto de la barra de estado.

    Las restas de 20 es para que al moverlos no se salgan del panel, es un margen.

    Además pulsando la tecla Delete y Supr se borra el pictureBox activo.

     

    Espero que a alguien le pueda resultar de utilidad.

     

    Muchas gracias!

    • Marked as answer by jmagago Saturday, October 16, 2010 5:08 PM
    Friday, October 15, 2010 4:41 AM

All replies

  • hola

    los controles picturebox los estas crerando dinamicamente desde codigo ?

    si es asi al momento de crear cada uno le asignas el evento con estas lineas

    pict.KeyDown += new KeyEventHandler(pictureBox_KeyDown);      

    pict.KeyPress += new KeyPressEventHandler(pictureBox_KeyPress);

    esos eventos es por cada control que creas

     

    si pones un brekpoint en cada evento, KeyDown y KeyPress se detiene el codigo alli al accionar una tecla sobre estos controles ?

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Sunday, September 05, 2010 11:52 PM
  • ok, acabo de conseguir que el evento KeyPress para eliminar un pictureBox funcione, el proble es que solo me funciona con la teclade retroceso (codigo ASCII 8) mientras que la tecla SUPR (127) no la detecta.

    public void pictureBox_KeyPress(object sender, KeyPressEventArgs e)
        {
          PictureBox pict = (PictureBox)sender;
    
          if (e.KeyChar == Convert.ToChar(127) || e.KeyChar == Convert.ToChar(8))
          {
            panel.Controls.Remove(pict);
          }
        }
    
    ¿Por qué no detecta la tecla Supr?

    Sunday, September 05, 2010 11:52 PM
  • hola

    pero no funciona porque no lanza el evento, o porque no pasa por el if ?

    no has probado usando las teclas definidas en Keys

    Detectar la pulsación de teclas

    o sea suar algo como esto

    if (e.KeyChar ==  Convert.ToChar(Keys.Delete) ){

    }

     


    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Monday, September 06, 2010 12:00 AM
  • Sisi, creo los pictureBox dinámicamente y la vez q los creo, les asigno los eventos manejadores.

    De momento el de eliminar funcionar pero solo con la tecla Retroceso, pero no con suprimir.

     

    En cuanto a lo de los breakpoint, si no los pongo en los Switch me da error en el código. Ya digo q con el evento KeyUp funcionaba, entonces no sé porque no va con el KeyDown.

    Monday, September 06, 2010 12:04 AM

  • si no los pongo en los Switch me da error en el código.

    eso si es bastante raro, se podrias saber cual es el mensaje de error

     

    digo q con el evento KeyUp funcionaba, entonces no sé porque no va con el KeyDown

    en el evento KeyDown que no funciona que error estas tenieendo ? digo si es que tienes un error

    puede que en el KeyDown no funcione porque este evento se produce antes de los evento keypress y keyup, cuando el control aun esta presnete, si lo eliminas aun estando dentro de evento este pierde la referencia al control que lo lanzo

    en cambio en KeyUp es un evento que se produce practicamente terminado la accion, por lo que quitar el control no lo afecta, ojo esto igual es una teoria que se me ocurre, la verdad no la valide

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Monday, September 06, 2010 12:10 AM
  • Cuando en el Switch le quito los break;

    me sale el siguiente error, uno por cada case.

    "El control no puede pasar explícitamente de una etiqueta de caso a otra ('case 37:)"

    "El control no puede pasar explícitamente de una etiqueta de caso a otra ('case 38:)"

    "El control no puede pasar explícitamente de una etiqueta de caso a otra ('case 39:)"

    "El control no puede pasar explícitamente de una etiqueta de caso a otra ('case 40:)"

     

    En cuanto a lo del KeyDown, no me da ningún error,

    puede que en el KeyDown no funcione porque este evento se produce antes de los evento keypress y keyup, cuando el control aun esta presnete, si lo eliminas aun estando dentro de evento este pierde la referencia al control que lo lanzo

    No, no, el eliminar el pictureBox y el intentar moverlo por el panel con el KeyDown son cosas independientes, primero intento moverlo con las teclas de dirección del teclado, y si se quiere eliminar pues se elimina, lo único q no sé porque no puedo eliminarlo con la tecla Supr y si con la de retroceso.

     

    Saludos

    Monday, September 06, 2010 12:21 AM
  • Sigo intentando con el evento KeyPress para eliminar el pictureBox, la cuestión es que funciona el evento, pero solo funciona si presiono la tecla Retroceso, si pongo cualquier otra no funciona.

    Además de retroceso necesito que también capture el evento la tecla Supr.

     

    public void pictureBox_KeyPress(object sender, KeyPressEventArgs e)
    {
    PictureBox pict = (PictureBox)sender;

    if (e.KeyChar == Convert.ToChar(Keys.Back) || e.KeyChar == Convert.ToChar(Keys.Delete))
    {
    panel.Controls.Remove(pict);
    ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "PictureBox eliminado";
    }
    }
    Saludos!

     

    Monday, September 06, 2010 1:01 AM
  • Hola, acabo de leer y comprobar, que el evento KeyDown no funciona con las teclas de dirección del teclado, solo con KeyUp.

    No sé si es del todo cierto o cómo poder solucionarlo, lo que sé es que lo he comprobado, he asigando los movimientos de las teclas de dirección a las letras A,W,S,D y funciona, el pictureBox se mueve libremente por todo el panel e incluso si se deja apretada la tecla lo hace continuadamente que es lo que yo quería.

    ¿Alguna forma de poder arreglarlo?

     

    Saludos!

    Monday, September 06, 2010 2:05 AM
  • hola

    si has puesto un breakpoint en el evento, y al presionar Delete, este se detiene ? si es asi, entonces al pasar el mouse sobre e.KeyChar que valor visualizas ?

    esto lo consulto para validar que codigo esta retornando la tecla Supr, valida que sea igual a Convert.ToChar(Keys.Back)

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Monday, September 06, 2010 12:33 PM
  • Hola, mmm, no entendí muy bien. El evento KeyDown para mover el pictureBox es totalmente independiente del KeyPress para eliminar el pictureBox aunque puedes mover el pictureBox por el panel y luego eliminarlo pero no al revés .

    Este evento funciona, lo único que no funciona es la parte "e.KeyChar == Convert.ToChart(Keys.Delete)"

    public void pictureBox_KeyPress(object sender, KeyPressEventArgs e)
        {
          PictureBox pict = (PictureBox)sender;
    
          if (e.KeyChar == Convert.ToChar(Keys.Back) || e.KeyChar == Convert.ToChar(Keys.Delete))
          {
            panelPictogramas.Controls.Remove(pict);
            ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "eliminado";
          }
        }
    

    No sé porqué no captura la tecla Supr, sin embargo la de Retroceso (la que está encima del enter) sí la coge.

    --------------------------------------------------------------------

    --------------------------------------------------------------------

    En cuanto a mover el pictureBox por el panel, sigo sin dar cn la solución de porqué no puedo asignarle a las teclas de dirección el evento KeyDown, pero sin embargo, si les asigno cualquier otra letra del teclado, el pictureBox se mueve. Por eso, no creo que sea problema de los breaks.

    public void pictureBox_KeyDown(object sender, KeyEventArgs e)
        {
          PictureBox pict = (PictureBox)sender;
    
          switch (e.KeyCode)
          {
            case (Keys.A): //left arrow
            {
              pict.Left -= 10;
              break;
            }
            case (Keys.W)://up arrow
            {
              pict.Top -= 10;
              break;
            }
            case (Keys.D): //right arrow
            {
              pict.Left += 10;
              break;
            }
            case (Keys.S): //down arrow
            {
              pict.Top += 10;
              break;
            }
          }
        }
    

    Así funciona perfectamente, pero si pongo 'Keys.Up' , 'Keys.Down', 'Keys.Left', 'Keys.Right' ya no funciona.

     

    Saludos

    Monday, September 06, 2010 2:09 PM
  • hola

    has probado capturando el Keys.Delete pero en el evento KeyDown ? para eso usa el KeyCode

    se que a veces hay evento que funcionan mejor con uno que con el otro

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Monday, September 06, 2010 2:12 PM
  • He encontrado este párrafo en un libro de Visual C# 2010

    "A diferencia de los eventos KeyDown y KeyUp, el evento KeyPress se genera solamente cuando se introduce un carácter ASCII. Esta definición excluye teclas especiales, como teclas de función (F1 a F12), teclas de movimiento de cursor (<- , -> , ...) o la tecla Supr (Del)."

     

    Monday, September 06, 2010 2:20 PM
  • Acabo de probar con KeyUp en vez de KeyDown para eliminar el pictureBox y la cosa es que funciona tanto la tecla Supr como la tecla Retroceso pero sigo sin saber porqué :(

    Me parece mejor usar el KeyDown, pero bueno.....

    En cuanto a las teclas de dirección para mover el pictureBox también funciona con el KeyUp :( pero yo necesito que funcione con el KeyDown, porque así al dejar la tecla pulsada se mueve rápidamente por el panel.

    Si me pudiera ayudar se lo agradecería.

    Gracias de nuevo.

    Monday, September 06, 2010 3:14 PM
  • hola, 

    nos puedes contar como concluyo este tema?


    Juan Carlos Ruiz Pacheco - Microsoft MVP Visual C#
    Visita mi blog:

    C#, XNA, Win32 - http://juank.black-byte.com

    Twitter: @JuanKRuiz
    Facebook: Arquitecto de Software

    Monday, October 11, 2010 7:01 PM
  • Hola Juan Carlos!, acabo de ver el post de casualidad, ya no me llegan al correo el aviso de que tengo respuestas en los posts. Pues el tema concluyo en que al final no use KeyDown, ni KeyUp, ni KeyPress.

    Algunos no iban como deberian ir, o no capturaban todas las teclas, asi que al final use el método "ProcessCmdKey".

    Es un evento que no entiendo muy bien cómo funciona pero al parecer es parecido al KeyDown o KeyPress.

    Escribí el método de la siguiente forma:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
          if ((keyData != Keys.Up && keyData != Keys.Down && keyData != Keys.Left && keyData != Keys.Right && keyData != Keys.Delete && keyData != Keys.Back))
            return base.ProcessCmdKey(ref msg, keyData);
    
          //Control que actualmente tiene el foco
          if (pictActivo == null)
            return base.ProcessCmdKey(ref msg, keyData);
          else
          {
            switch (keyData)
            {
              case Keys.Up: // up
                if ((pictActivo.Top - 5) > 25)
                {
                  pictActivo.Top -= 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Top = 20;
                break;
              case Keys.Left: // Left
                if ((pictActivo.Left - 5) > 20)
                {
                  pictActivo.Left -= 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Left = 20;
                break;
              case Keys.Right: // right
                if ((pictActivo.Left + pictActivo.Width + 5) < (panelPictogramas.Width - 20))
                {
                  pictActivo.Left += 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Left = panelPictogramas.Width - pictActivo.Width - 20;
                break;
              case Keys.Down: // down
                if ((pictActivo.Top + pictActivo.Height + 5) < (panelPictogramas.Height - 25))
                {
                  pictActivo.Top += 5;
                  imprimirCoodenadas(pictActivo);
                  ((FormPadre)this.ParentForm).EtiquetaPrincipalBarraEstado.Text = "Pictograma movido";
                }
                else
                  pictActivo.Top = panelPictogramas.Height - pictActivo.Height - 20;
                break;
              case Keys.Delete:
                ((FormPadre)this.ParentForm).btnBorrar.PerformClick();
                break;
              case Keys.Back:
                ((FormPadre)this.ParentForm).btnBorrar.PerformClick();
                break;
            }
          }
          return base.ProcessCmdKey(ref msg, keyData);
        }
    

    Básicamente, con las teclas de dirección mueve el pictureBox activo, después imprimo las coordenadas del pictureBox y cambio el texto de la barra de estado.

    Las restas de 20 es para que al moverlos no se salgan del panel, es un margen.

    Además pulsando la tecla Delete y Supr se borra el pictureBox activo.

     

    Espero que a alguien le pueda resultar de utilidad.

     

    Muchas gracias!

    • Marked as answer by jmagago Saturday, October 16, 2010 5:08 PM
    Friday, October 15, 2010 4:41 AM