Colabora .NET

Extender propiedades y métodos de controles

Basado en los artículos y códigos de Guillermo Som y sus colaboradores

 

Fecha: 23/Oct/2006  (20-10-06)
Autor: José Antonio Wildt Mujica. - [email protected]

 


Introducción

He visto en tus publicaciones y en algunas otras colaboraciones de éste sitio el tema de la extensión de propiedades y métodos de los controles, y tomando el curso de Guille sobre el tema, aplicando ese código que publicó en su artículo, he hecho tres controlcillos que para mi son de gran utilidad, pues en ellos englobé todo el código repetitivo que siempre tengo en mis aplicaciones, no dudo que estos controles sean mejorables, eso lo dejo a Guillermo y a quienes deseen colaborar en este proyecto. Estoy a vuestras ordenes para eso.

La idea principal es hacer que las validaciones de un control TextBox para que solo acepte números o fechas se haga una sola vez y que sea reutilizable para el resto de nuestras aplicaciones, que las validaciones de un control de texto nos eliminen del camino las comillas simples (') que al momento de crear una consulta SQL Insert o Update nos rompe en un error que terminamos por validar, típico de guardar en una base de datos el nombre de un fulano cuyo apellido es D'acosta, Pedro... Permitir que un usuario coloque una fecha casi que en el formato que desee y que nuestro control la convierta en algo ordenado, o poder dar la posibilidad al usuario de tener una calculadora a mano que envíe el resultado de una operación a nuestro control; en los controles que aquí presento el calendario y la calculadora los podéis llamar presionando la tecla "m" en el control correspondiente.

Los controles son:

  1.  TextBoxDate

  2.  TextBoxCalc

  3.  TextBoxSQL

Todos basados en tu  TextBoxNum

 

Contenido

Pues bien, todos los controles son sensibles a la tecla ENTER para pasar de un control a otro, en todos se puede configurar si así lo deseamos, que al tomar el foco cambie su color de fondo y que al perderlo retorne a su color de fondo original, todos están validados para que solo acepten los caracteres que sean permitidos según el formato que se vaya a utilizar, estas son propiedades comunes de los controles.

Detallando:

En el TextBoxDate encontraremos:

1.- El usuario puede introducir valores de fecha sin separadores o con ellos, es decir, valores tales como por ejemplo:

  • 010303 para ser convertido en 01/03/2003

  • 561 para ser convertido en 05/06/2001

  • 7/8/02 para ser convertido en 07/08/2002

Entre otros...

Si el valor que introduce el usuario es totalmente inválido el control quedará en blanco

El programador puede seleccionar entre los formatos de fecha “dd/mm”, “mm/dd”, “dd/mm/aaaa” o “mm/dd/aaaa” desde su lista de propiedades.

Puede en dicha lista seleccionar el color de fondo al tomar el foco y al perderlo.

Puede presionar la tecla “m” (Mayúscula o Minúscula) para mostrar un calendario mediante el cual el usuario pueda seleccionar una fecha, y con la tecla Escape “ESC” puede cerrar el calendario si no desea usar la X de cerrar el formulario y cancelar el input de una fecha.

El programador cuenta con una Función llamada “ToStrSQL()” mediante la cual se retorna la fecha del control en formato “aaaammdd” para ser utilizada en sentencias SQL y la Función llamada “ToBuscarSQL” que retorna el valor del control en formato “#aaaa/mm/dd#” para ser utilizado en búsquedas SQL.

Si el control está en blanco las funciones antes mencionadas retornaran un String “NULL”.

Nota:
El resto de los controles tienen el mismo principio es cosa de que lo vean un poco y lo entenderán espero que estos controles sean de su agrado y les sirvan tanto como a mi.

 

El código:

Este es solo el código del control TextBoxDate el resto de los controles no los detallo en la página para no aburriros con más de lo mismo pero podréis verlo en el proyecto.

A continuación el código en Visual Basic:

Imports SendKey = System.Windows.Forms.SendKeys
Imports System.Reflection
Imports System.ComponentModel

Public Class TextBoxDate
    Inherits System.Windows.Forms.TextBox

    Private _tipoFormato As TipoFormato ' indica el tipo de formato que obtendrá el control
    Protected digitos() As Char ' Array para los dígitos válidos
    Private _ColorFoco As Color ' Color Asignado cuando el control tiene el foco
    Private _ColorFuera As Color ' Color Asignado cuando el control pierde el foco
    Private ContieneFoco As Boolean = False ' Indica en que momento el control tiene el foco

    Public Enum TipoFormato
        <Description("dd/mm")> dd_mm = 1
        <Description("mm/dd")> mm_dd = 2
        <Description("dd/mm/aaaa")> dd_mm_aaaa = 3
        <Description("mm/dd/aaaa")> mm_dd_aaaa = 4
    End Enum

    <Category("Behavior"), DefaultValue(GetType(Color), "AliceBlue"), _
    Description("Indica el color de fondo que tomará el control al obtener el foco")> _
    Public Property ColorFoco() As Color
        'Color cuando el control toma el foco
        Get
            Return _ColorFoco
        End Get
        Set(ByVal Value As Color)
            _ColorFoco = Value
        End Set
    End Property

    <Category("Behavior"), DefaultValue(GetType(Color), "White"), _
    Description("Indica el color de fondo que tomará el control al perder el foco")> _
    Public Property ColorFuera() As Color
        'Color cuando el control pierde el foco
        Get
            Return _ColorFuera
        End Get
        Set(ByVal Value As Color)
            _ColorFuera = Value
        End Set
    End Property

    <Category("Behavior"), DefaultValue(GetType(TipoFormato), "dd/mm/aaaa"), _
    Description("Indica el tipo de Formato de fecha admitido")> _
    Public Overridable Property TipoDato() As TipoFormato
        ' El tipo de datos que admite el control
        Get
            Return _tipoFormato
        End Get
        Set(ByVal value As TipoFormato)
            ' cambiar el array para que solo acepte los valores indicados
            Dim s As String
            _tipoFormato = value

            Select Case _tipoFormato
                Case TipoFormato.dd_mm
                    s = "0123456789/"
                    MyBase.MaxLength = 5
                Case TipoFormato.mm_dd
                    s = "0123456789/"
                    MyBase.MaxLength = 5
                Case TipoFormato.dd_mm_aaaa
                    s = "0123456789/"
                    MyBase.MaxLength = 10
                Case TipoFormato.mm_dd_aaaa
                    s = "0123456789/"
                    MyBase.MaxLength = 10
            End Select
            ' se agrega el caracter de reroceso o borrado al array
            digitos = (s & ChrW(8)).ToCharArray
        End Set
    End Property

    Public Sub New()
        ' En el constructor asignamos el tipo predeterminado
        MyBase.New()
       
        'Valores por defecto del control
        Me._tipoFormato = TipoFormato.dd_mm
        Me.ColorFoco = Color.AliceBlue
        Me.ColorFuera = Color.White
        MyBase.TextAlign = HorizontalAlignment.Center
        MyBase.MaxLength = 5
        MyBase.Text = ""
    End Sub

    Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
        'algunas veces el evento OnGotFocus no se dispara
        'debido a ello coloco el código en este evento para 
        'seleccionar todo lo que esté escrito en el control.
        MyBase.SelectAll()
    End Sub

    Protected Overridable Function TeclaValida(ByVal c As Char) As Boolean
        'Comprueba si el caracter indicado es uno de los valores aceptados
        Return (Array.IndexOf(digitos, c) > -1)
    End Function

    Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
        Dim StrTDia As Integer
        Dim StrTMes As Integer
        Dim StrTAnio As Integer

        Dim FechaTemporal As String 'la uso para guardar la fecha en formato dd/mm/yyyy
        'independientemente del formato del sistema.

        Dim TPlantilla As String 
	' lo uso para rellenar el formato seleccionado por el programador

        If e.KeyChar = Chr(13) Then
            'indica al control que simule la tecla tab al presionar ENTER
            e.Handled = True
            SendKey.Send("{tab}")
        End If
        'admitir solo teclas numéricas y la "/"
        If e.KeyChar = "m" Or e.KeyChar = "M" Then
            'Muestra el Calendario al usuario
            Dim Calen As New FrmCalen
            StrResCalen = ""  'elimino cualquier contenido anterior de la variable
            Calen.ShowDialog()
            If StrResCalen <> "ESC" Then
                'si el usuario salio del calendario con escape sin seleccionar alguna fecha
                'lo valido para salir del evento
                If StrResCalen <> "" Then
                    'ingresar la fecha seleccionada 
                    'según el formato seleccionado
                    StrTDia = Val(StrResCalen.Substring(0, 2))
                    StrTMes = Val(StrResCalen.Substring(3, 2))
                    StrTAnio = Val(StrResCalen.Substring(6, 4))

                    'éste código lo hago debido a que la configuración 
                    'regional del sistema puede variarme el formato de fecha
                    'así se que 01/02/2006 es 1 de febrero y no 2 de enero.
                    Select Case _tipoFormato
                        Case TipoFormato.dd_mm
                            TPlantilla = "dd/mm"
                        Case TipoFormato.mm_dd
                            TPlantilla = "mm/dd"
                        Case TipoFormato.dd_mm_aaaa
                            TPlantilla = "dd/mm/yyyy"
                        Case TipoFormato.mm_dd_aaaa
                            TPlantilla = "mm/dd/yyyy"
                    End Select
                    FechaTemporal = TPlantilla
                    FechaTemporal = Replace(FechaTemporal, "dd", StrTDia.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "mm", StrTMes.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "yyyy", StrTAnio.ToString("0000"))

                    MyBase.Text = FechaTemporal
                    Exit Sub
                End If
            End If
        End If
        If Asc(e.KeyChar) = 3 Then
            GoTo Salida
        End If
        'en este control no permito el uso de Ctrl+v
        'o la función de Windows de Pegar para evitar
        'mas validaciones
        'If Asc(e.KeyChar) = 22 Then
        '    If IsNumeric(MyBase.Text) Then
        '        GoTo Salida
        '    Else
        '        e.Handled = True
        '        Exit Sub
        '    End If
        'End If
        If TeclaValida(e.KeyChar) = False Then
            e.Handled = True
        End If
Salida:
        ' Seguimos ejecutando el evento en el control base
        MyBase.OnKeyPress(e)

    End Sub

    Public Function ToStrSQL() As String
        'este procedimiento es está hecho para funciones o 
        'consultas SQL en las cuales al momento de guardar
        'Formatea la fecha a formato 'yyyymmdd' que es uno 
        'de los formatos más compatibles para guardar una
        'fecha en una base de datos Microsoft Access o SQL
        Dim d As String
        Dim TPlantilla As String
        Dim FechaTemporal As String
        Dim StrTDia As Integer
        Dim StrTMes As Integer
        Dim StrTAnio As Integer
        Dim StrTAnioActual As Integer = Date.Now.Year

        d = Trim$(MyBase.Text)

        If d = "" Then
            d = "NULL"
            GoTo Salida
        End If

        Select Case _tipoFormato
            Case TipoFormato.dd_mm
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = StrTAnioActual
            Case TipoFormato.mm_dd
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = StrTAnioActual
            Case TipoFormato.dd_mm_aaaa
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = Val(MyBase.Text.Substring(6, 4))
            Case TipoFormato.mm_dd_aaaa
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = Val(MyBase.Text.Substring(6, 4))
        End Select

        TPlantilla = "yyyymmdd"
        TPlantilla = Replace(TPlantilla, "dd", StrTDia.ToString("00"))
        TPlantilla = Replace(TPlantilla, "mm", StrTMes.ToString("00"))
        TPlantilla = Replace(TPlantilla, "yyyy", StrTAnio.ToString("0000"))
        d = TPlantilla
Salida:
        Return d
    End Function

    Public Function ToBuscarSQL() As String
        'Este procedimiento es está hecho para funciones o 
        'consultas SQL en las cuales al momento de buscar
        'se Formatea la fecha a formato '#yyyy/m/d#' que es uno 
        'de los formatos más compatibles para buscar una
        'fecha en una base de datos Microsoft Access o SQL
        'He dejado la función en String para poder enviar
        'el valor NULL si el campo está vacío
        Dim d As String
        Dim TPlantilla As String
        Dim FechaTemporal As String
        Dim StrTDia As Integer
        Dim StrTMes As Integer
        Dim StrTAnio As Integer
        Dim StrTAnioActual As Integer = Date.Now.Year

        d = Trim$(MyBase.Text)

        If d = "" Then
            d = "NULL"
            GoTo Salida
        End If

        Select Case _tipoFormato
            Case TipoFormato.dd_mm
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = StrTAnioActual
            Case TipoFormato.mm_dd
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = StrTAnioActual
            Case TipoFormato.dd_mm_aaaa
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = Val(MyBase.Text.Substring(6, 4))
            Case TipoFormato.mm_dd_aaaa
                StrTDia = Val(MyBase.Text.Substring(0, 2))
                StrTMes = Val(MyBase.Text.Substring(3, 2))
                StrTAnio = Val(MyBase.Text.Substring(6, 4))
        End Select

        TPlantilla = "#yyyy/mm/dd#"
        TPlantilla = Replace(TPlantilla, "dd", StrTDia.ToString("00"))
        TPlantilla = Replace(TPlantilla, "mm", StrTMes.ToString("00"))
        'Elimino los posibles 0 (Ceros) del día y del mes
        TPlantilla = Replace(TPlantilla, "0", "")
        TPlantilla = Replace(TPlantilla, "yyyy", StrTAnio.ToString("0000"))

        d = TPlantilla
Salida:
        Return d
    End Function

    Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)
        ContieneFoco = False
        MyBase.BackColor = _ColorFuera
        MyBase.Text = ConstruyeFecha()
    End Sub

    Private Function ConstruyeAnio(ByVal mAnio As Integer) As String
        'Dim mYear As Integer
        Dim tmpYear As String
        If mAnio >= 1 And mAnio <= 30 Then
            tmpYear = "20" & mAnio.ToString("00")
        ElseIf mAnio >= 31 And mAnio <= 99 Then
            tmpYear = "19" & mAnio.ToString("00")
        ElseIf mAnio >= 100 And mAnio <= 1760 Then
            tmpYear = "1900" 'esto puede tomarse como un error
        ElseIf mAnio >= 1761 And mAnio <= 2100 Then
            tmpYear = mAnio.ToString("0000")
        ElseIf mAnio = 0 Then
            tmpYear = "2000"
        End If
        ConstruyeAnio = tmpYear
    End Function

    Private Function ConstruyeFecha() As String
        Dim mTexto As String = Trim$(MyBase.Text) ' texto indicado por el usuario
        Dim LngmTexto As Integer = mTexto.Length ' longitud del texto indicado por el usuario
        Dim nfi_g As New System.Globalization.DateTimeFormatInfo
        Dim FechaTemporal As String = nfi_g.CurrentInfo.ShortDatePattern.ToString() 
	'retrona el formato de fecha corta del sistema
        Dim mDia As Integer ' guarda el día que introdujo el usuario
        Dim mMesActual As Integer = Date.Now.Month() ' guarda el número de mes actual 
        Dim mAnioActual As Integer = Date.Now.Year ' guarda el número de año actual 
        Dim mMes As Integer ' guarda el mes que introdujo el usuario
        Dim mAnio As Integer ' guarda el año que introdujo el usuario
        Dim strmAnio As String ' será el string a utilizar en el año
        Dim tFec() As String ' se usa para aplicar un split al dato introducido
        Dim Bloques As Integer ' Denomino Bloques a cada cifra separada por una "/"
        Dim strPlantilla As String ' es una plantilla del formato para mostrar

        'Saber cuantos bloques definió el usuario
        tFec = Split(mTexto, "/")
        Bloques = tFec.Length()

        'primera validacion
        If Bloques > 3 Then
            'si el usuario indica mas de 2 "/"
            'ese formato no es válido
            ConstruyeFecha = ""
            Exit Function
        End If

        'segunda validación
        If InStr(MyBase.Text, "//") > 0 Then
            'si el usuario introduce 2 "//" unidas 
            'el formato no es válido
            ConstruyeFecha = ""
            Exit Function
        End If

        Select Case Bloques
            Case 1
                'un solo bloque significa que el usuario escribió
                'una cifra cuya longitud puede ser menor o igual
                'al formato seleccionado. De aquí se desprenden 
                'varias opciones que se deben analizar por la 
                'longitud de este único bloque en cuestión.
                'la longitud del bloque puede estar entre 1 y 8
                'caracteres numéricos, siendo las longitudes mas usadas

                '1 => Día
                '2 => Día
                '3 => 1y2 = Día & 3 =Mes
                '4 => 1y2 = Día & 3y4 =Mes
                '5 => 1y2 = Día & 3y4 =Mes & 5 = Año(entre 2000 y 2009)

                '6 => 1y2 = Día & 3y4 =Mes & 5y6 Donde
                'si Año>=10 y Año <= 30 entonces Año estará entre 2010 y 2030
                'si Año>=31 y Año <= 99 entonces Año estará entre 1931 y 1999
                ' y demás validaciones realizadas en la función ConstruyeAnio

                '7 => 1y2 = Día & 3y4 =Mes & AñoActual y se omiten las 3
                'últimas cifras para evitar errores

                '8 => 1y2 = Día & 3y4 =Mes & 5 al 8 Año

                '9 o 10 cifras se dejará en blanco para evitar errores

                Select Case mTexto.Length()
                    Case 0
                        FechaTemporal = ""
                        Exit Function
                    Case 1
                        mDia = Val(mTexto)
                        If DiaEsValido(mDia, mMesActual) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", _
				mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", _
				mMesActual.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", _
				mMesActual.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                            FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                        Else
                            'es posible que el único digito sea 0
                            'en ese caso
                            FechaTemporal = ""
                            Exit Function
                        End If
                    Case 2
                        mDia = Val(mTexto)
                        If DiaEsValido(mDia, mMesActual) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", _
				mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", _
				mMesActual.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", _
				mMesActual.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                            FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                        Else
                            'si por ejemplo el usuario digitó 56 se deberá 
                            'convertir en día 5 del mes 6
                            mDia = Val(mTexto.Substring(0, 1))
                            mMes = Val(mTexto.Substring(1, 1))
                            If DiaEsValido(mDia, mMes) = True Then
                                FechaTemporal = Replace(FechaTemporal, "dd", _
				mDia.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "mm", _
				mMes.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "MM", _
				mMes.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                                FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                            Else
                                FechaTemporal = ""
                            End If
                        End If
                    Case 3
                        mDia = Val(mTexto.Substring(0, 2))
                        mMes = Val(mTexto.Substring(2, 1))
                        If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                            FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                        Else
                            mDia = Val(mTexto.Substring(0, 1))
                            mMes = Val(mTexto.Substring(1, 2))
                            If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                                FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                                FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                            Else
                                mDia = Val(mTexto.Substring(0, 1))
                                mMes = Val(mTexto.Substring(1, 1))
                                strmAnio = ConstruyeAnio(Val(mTexto.Substring(2, 1)))
                                If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                                    FechaTemporal = Replace(FechaTemporal, "dd", _
					mDia.ToString("00"))
                                    FechaTemporal = Replace(FechaTemporal, "mm", _
					mMes.ToString("00"))
                                    FechaTemporal = Replace(FechaTemporal, "MM", _
					mMes.ToString("00"))
                                    FechaTemporal = Replace(FechaTemporal, "yyyy", strmAnio)
                                    FechaTemporal = Replace(FechaTemporal, "aaaa", strmAnio)
                                Else
                                    FechaTemporal = ""
                                End If
                            End If
                        End If
                    Case 4
                        mDia = Val(mTexto.Substring(0, 2))
                        mMes = Val(mTexto.Substring(2, 2))
                        If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                            FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                        Else
                            mDia = Val(mTexto.Substring(0, 1))
                            mMes = Val(mTexto.Substring(1, 1))
                            strmAnio = ConstruyeAnio(Val(mTexto.Substring(2, 2)))
                            If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                                FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                                FechaTemporal = Replace(FechaTemporal, "yyyy", strmAnio)
                                FechaTemporal = Replace(FechaTemporal, "aaaa", strmAnio)
                            Else
                                FechaTemporal = ""
                            End If
                        End If
                    Case 5
                        mDia = Val(mTexto.Substring(0, 2))
                        mMes = Val(mTexto.Substring(2, 2))
                        strmAnio = ConstruyeAnio(Val(mTexto.Substring(4, 1)))
                        If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", strmAnio)
                            FechaTemporal = Replace(FechaTemporal, "aaaa", strmAnio)
                        Else
                            FechaTemporal = ""
                        End If
                    Case 6
                        mDia = Val(mTexto.Substring(0, 2))
                        mMes = Val(mTexto.Substring(2, 2))
                        strmAnio = ConstruyeAnio(Val(mTexto.Substring(4, 2)))
                        If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", strmAnio)
                            FechaTemporal = Replace(FechaTemporal, "aaaa", strmAnio)
                        Else
                            FechaTemporal = ""
                        End If
                    Case 7
                        mDia = Val(mTexto.Substring(0, 2))
                        mMes = Val(mTexto.Substring(2, 2))
                        If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", _
				mAnioActual.ToString("0000"))
                            FechaTemporal = Replace(FechaTemporal, "aaaa", _
				mAnioActual.ToString("0000"))
                        Else
                            FechaTemporal = ""
                        End If
                    Case 8
                        mDia = Val(mTexto.Substring(0, 2))
                        mMes = Val(mTexto.Substring(2, 2))
                        strmAnio = ConstruyeAnio(Val(mTexto.Substring(4, 4)))
                        If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                            FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                            FechaTemporal = Replace(FechaTemporal, "yyyy", strmAnio)
                            FechaTemporal = Replace(FechaTemporal, "aaaa", strmAnio)
                        Else
                            FechaTemporal = ""
                        End If
                    Case 9
                        FechaTemporal = ""
                    Case 10
                        FechaTemporal = ""
                End Select

            Case 2
                'dos bloques indicaría que el usuario escribió 2 cifras
                'separadas por una barra "/", esto nos deja asumir que 
                'el usuario indicó un día y un mes
                mDia = Val(tFec(0))
                mMes = Val(tFec(1))
                If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                    FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "yyyy", _
			mAnioActual.ToString("0000"))
                    FechaTemporal = Replace(FechaTemporal, "aaaa", _
			mAnioActual.ToString("0000"))
                Else
                    FechaTemporal = ""
                End If
            Case 3
                'tres bloques indicaría que el usuario escribió 3 cifras
                'separadas por una barra "/", esto nos deja asumir que 
                'el usuario indicó un día, un mes y un año
                mDia = Val(tFec(0))
                mMes = Val(tFec(1))
                strmAnio = ConstruyeAnio(Val(tFec(2)))
                If MesEsValido(mMes) = True And DiaEsValido(mDia, mMes) = True Then
                    FechaTemporal = Replace(FechaTemporal, "dd", mDia.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "mm", mMes.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "MM", mMes.ToString("00"))
                    FechaTemporal = Replace(FechaTemporal, "yyyy", strmAnio)
                    FechaTemporal = Replace(FechaTemporal, "aaaa", strmAnio)
                Else
                    FechaTemporal = ""
                End If
        End Select
        Dim tFecha As Date
        If FechaTemporal <> "" Then
            tFecha = Date.Parse(FechaTemporal)
            Select Case _tipoFormato
                Case TipoFormato.dd_mm
                    strPlantilla = tFecha.Day.ToString("00") & "/" & _
			tFecha.Month.ToString("00")
                Case TipoFormato.mm_dd
                    strPlantilla = tFecha.Month.ToString("00") & "/" & _
			tFecha.Day.ToString("00")
                Case TipoFormato.dd_mm_aaaa
                    strPlantilla = tFecha.Day.ToString("00") & "/" & _
			tFecha.Month.ToString("00") & "/" & _
			tFecha.Year.ToString("0000")
                Case TipoFormato.mm_dd_aaaa
                    strPlantilla = tFecha.Month.ToString("00") & "/" & _
			tFecha.Day.ToString("00") & "/" & _
			tFecha.Year.ToString("0000")
            End Select
        End If
        ConstruyeFecha = strPlantilla

    End Function

    Private Function DiaEsValido(ByVal mDia As Integer, ByVal mMes As Integer) As Boolean
        'verifico que el valor día sea válido dentro del valor mes
        'así puedo validar que el usuario no intente agregarme 
        'una fecha como 30 de febrero
        If mMes >= 1 And mMes <= 12 Then
            mMes = mMes
        Else
            mMes = Date.Now.Month()
        End If
        If mDia >= 1 And mDia <= UltimoDeMes(mMes) Then
            DiaEsValido = True
        Else
            DiaEsValido = False
        End If
    End Function

    Private Function MesEsValido(ByVal mMes As Integer) As Boolean
        'validar que el valor mes esté en el rengo de 1 a 12 meses
        Dim TmpMesValido As Boolean
        If mMes >= 1 And mMes <= 12 Then
            TmpMesValido = True
        Else
            TmpMesValido = False
        End If
        MesEsValido = TmpMesValido
    End Function

    Private Function UltimoDeMes(ByVal mMes As Integer) As Integer
        'indica cual es el último día del presente mes
        Dim fecha As Date = Date.Now()
        Dim FinDelMes As Date
        FinDelMes = DateAdd("m", 1, fecha)
        FinDelMes = DateSerial(Year(FinDelMes), Month(FinDelMes), 1)
        FinDelMes = DateAdd("d", -1, FinDelMes)
        UltimoDeMes = FinDelMes.Day
    End Function

    Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
        'se establece el color de fondo del control al tomar el foco
        'la variable ContieneFoco se establece como verdadera para
        'que al cambiar el contenido del TextXox sepamos si lo esta
        'haciendo desde el control o desde otra función, como podría 
        'ser al momento de llenar el control desde una base de datos
        MyBase.BackColor = _ColorFoco
        ContieneFoco = True
        MyBase.SelectAll()
    End Sub
End Class

 

Pantallas de los controles.

Esto sería mas o menos la cara de los controles...


...


Espacios de nombres usados en el código de este artículo:

Imports System.Windows.Forms.SendKeys
Imports System.Reflection
Imports System.ComponentModel

 


Código de ejemplo (ZIP):

 

Fichero con el código de ejemplo: jwildt_TextBoxNumCalcDate.zip - 47.9 KB

(MD5 checksum: 32FBD7A72D5D547B4B05688B2141FB6F)

 


ir al índice principal del Guille