Validar Entry en Gtk#

By rtmex

Recientemente necesitaba validar un “Entry” en gtk-sharp para que el usuario sólo pudiera capturar números. Nunca antes había programado en Mono y tampoco había desarrollado interfaces gráficas usando Gtk o Gtk#, asi que probablemente este post le sea útil únicamente a novatos en Mono y Gtk# ( como yo :) ).

Buscando en internet encontré 2 posts, de los cuales tome código y le hice pequeñas adecuaciones para crear 2 clases que son subclases de la clase Entry.

Lo que hace el código es capturar el evento KeyPress y verificar la tecla que pulsó el usuario, a partir de ahi decide si es una tecla o caracter permitido o no.

Creé una clase llamada EntryEnteros y una clase llamada EntryDecimales. Las clases son casí idénticas, la diferencia es que la segunda acepta el punto como caracter permitido y la primera no. Esto implica que en la segunda clase se agrega el caracter “.” en la cadena s_charvalidos pero también se captura cuando el usuario pulsa el punto del teclado numérico (Gdk.Key.KP_Decimal).

El código del post http://nexus.developarts.com/limitar_la_captura_de_un_entry#comment-769 no funciona si el usuario usa el teclado numérico para introducir datos, sólo acepta los números de la parte superior del teclado; tampoco permite al usuario moverse con las flechas izquierda o derecha. El código que me sirvió de base para incluir eso está en el post http://mbrenes.blogspot.com/2007_02_01_archive.html pero es para Gtk, así que sólo hice los cambios necesarios para pasarlo a Gtk#.

Este ejemplo fue realizado en Debian Lenny

Esta es la clase EntryEnteros

/* Archivo entryenteros.cs */

using System;
using Gtk;

public class EntryEnteros : Entry
{
   public EntryEnteros()
   {
      KeyPressEvent +=  new KeyPressEventHandler(TeclaPulsada);
   }

   // Conectamos el manejador de eventos antes del evento KeyPress
   [GLib.ConnectBefore ()]

   private void TeclaPulsada(object o, KeyPressEventArgs args)
   {
      string s_charvalidos = "0123456789";

      // Para que al pulsar enter el foco se pase al siguiente control
      if (args.Event.Key == Gdk.Key.Return || args.Event.Key == Gdk.Key.KP_Enter)
         {           
          Toplevel.ChildFocus (DirectionType.TabForward);
          args.RetVal = true;
         }
      else
          // Solo se permiten los caracteres en s_charvalidos, los números del teclado numérico (KP_0...),
          // el backspace, el delete, flecha izquierda, flecha derecha
          if (Array.IndexOf(s_charvalidos.ToCharArray(), Convert.ToChar(args.Event.Key)) == -1 && args.Event.Key!=Gdk.Key.BackSpace && args.Event.Key!=Gdk.Key.Delete && args.Event.Key!=Gdk.Key.Left && args.Event.Key!=Gdk.Key.Right && !(args.Event.Key >=Gdk.Key.KP_0 && args.Event.Key <=Gdk.Key.KP_9))
              args.RetVal = true;     
   }
}

Esta es la clase EntryDecimales

/* Archivo entrydecimales.cs */

using System;
using Gtk;

public class EntryDecimales : Entry
{
   public EntryDecimales()
   {
      KeyPressEvent +=  new KeyPressEventHandler(TeclaPulsada);
   }

   // Conectamos el manejador de eventos antes del evento KeyPress
   [GLib.ConnectBefore ()]

   private void TeclaPulsada(object o, KeyPressEventArgs args)
   {
      string s_charvalidos = "0123456789.";

      // Para que al pulsar enter el foco se pase al siguiente control
      if (args.Event.Key == Gdk.Key.Return || args.Event.Key == Gdk.Key.KP_Enter)
         {           
          Toplevel.ChildFocus (DirectionType.TabForward);
          args.RetVal = true;
         }
      else
          // Solo se permiten los caracteres en s_charvalidos, los números del teclado numérico (KP_0...),
          // el backspace, el delete, flecha izquierda, flecha derecha
          if (Array.IndexOf(s_charvalidos.ToCharArray(), Convert.ToChar(args.Event.Key)) == -1 && args.Event.Key!=Gdk.Key.BackSpace && args.Event.Key!=Gdk.Key.Delete && args.Event.Key!=Gdk.Key.Left && args.Event.Key!=Gdk.Key.Right && args.Event.Key!=Gdk.Key.KP_Decimal && !(args.Event.Key >=Gdk.Key.KP_0 && args.Event.Key <=Gdk.Key.KP_9))
              args.RetVal = true;     
   }
}

Con el siguiente programa podemos probar nuestras 2 clases

/* Archivo prueba.cs */

using System;
using Gtk;

public class prueba
{
    public static void Main()
    {
        Application.Init();
        Window w_principal = new Window("Limitar captura en un Entry");
        w_principal.DeleteEvent += delete_event;

        EntryEnteros e_cantidad = new EntryEnteros ();
        EntryDecimales e_precio = new EntryDecimales ();
        HBox hb_cantidad = new HBox (true, 0);
        HBox hb_precio = new HBox (true, 0);
        VBox vb_contenedor = new VBox();

        hb_cantidad.PackStart (new Label ("Cantidad: "), false, false, 0);
        hb_cantidad.PackStart (e_cantidad);
        hb_precio.PackStart (new Label ("Precio: "), false, false, 0);
        hb_precio.PackStart (e_precio);
        vb_contenedor.PackStart (hb_cantidad, true, true, 0);
        vb_contenedor.PackStart (hb_precio, true, true, 0);

        w_principal.Add(vb_contenedor);
        w_principal.ShowAll();
        Application.Run();
    }

    static void delete_event (object obj, DeleteEventArgs args)
    {
        Application.Quit();
    }
}

Compilamos

gmcs -pkg:gtk-sharp-2.0 prueba.cs entryenteros.cs entrydecimales.cs

Con esto tenemos nuestro archivo prueba.exe, el cual ejecutamos tecleando ./prueba.exe

A continuación una captura de la pantalla ya con datos introducidos

prueba

Etiquetas: , ,

2 comentarios para “Validar Entry en Gtk#”

  1. rodrigo Dice:

    muy buena tu clases pero no he podido hacer que cuando presione la tecla ENTER cambie el foco a otro control. agradecería la ayuda. gracias

    • rtmex Dice:

      Hola rodrigo

      Ya he modificado las clases entryenteros y entrydecimales para que al pulsar Enter el foco se vaya al siguiente control.
      Espero sea lo que necesitabas.

      Saludos

Escribe un comentario