Foros del Web » Programando para Internet » ASPX (.net) »

Control compuesto personalizado

Estas en el tema de Control compuesto personalizado en el foro de ASPX (.net) en Foros del Web. Muy buenas. He hecho mi primer control personalizado. Se trata de una caja de texto para introducir un código postal de España y encuentre la ...
  #1 (permalink)  
Antiguo 16/04/2007, 09:19
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Control compuesto personalizado

Muy buenas. He hecho mi primer control personalizado. Se trata de una caja de texto para introducir un código postal de España y encuentre la provincia a la que pertenece. Os lo dejo por si le sirve a alguien y así de paso le sacáis defectos que los tendrá y a montones.

Un saludo.

Código:
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class controlCPProvincia
    : Inherits Control : Implements INamingContainer

    Private _idTxt As String
    Private _cpInicial As String

    Public Property IDTxt() As String
        Get
            Return _idTxt
        End Get
        Set(ByVal Value As String)
            _idTxt = Value
        End Set
    End Property

    Public Property CPInicial() As String
        Get
            Return _cpInicial
        End Get
        Set(ByVal Value As String)
            _cpInicial = Value
        End Set
    End Property

    Protected Overrides Sub CreateChildControls()
        Dim txt As New TextBox
        txt.MaxLength = "5"
        txt.Columns = "1"
        txt.ID = IDTxt
        txt.Text = CPInicial
        Dim lbl As New Label
        lbl.ID = "lbl" & IDTxt
        lbl.Text = "Provincia no identificada"
        'Script con vectores*****
        Dim sbScript As New System.Text.StringBuilder
        sbScript.Append("<script language=javascript>" & vbCrLf)
        sbScript.Append("var arrProvincias = new Array(" & _
                        "'&Aacute;lava','Albacete','Alicante','Almer&iacute;a'," & _
                        "'&Aacute;vila','Badajoz','Baleares','Barcelona'," & _
                        "'Burgos','C&aacute;ceres','C&aacute;diz','Castell&oacute;n'," & _
                        "'Ciudad Real','C&oacute;rdoba','Coru&ntilde;a','Cuenca'," & _
                        "'Gerona','Granada','Guadalajara','Guip&uacute;zcoa'," & _
                        "'Huelva','Huesca','Ja&eacute;n','Le&oacute;n'," & _
                        "'L&eacute;rida','La Rioja','Lugo','Madrid'," & _
                        "'M&aacute;laga','Murcia','Navarra','Orense'," & _
                        "'Asturias','Palencia','Las Palmas','Pontevedra'," & _
                        "'Salamanca','Santa Cruz de Tenerife','Cantabria','Segovia'," & _
                        "'Sevilla','Soria','Tarragona','Teruel'," & _
                        "'Toledo','Valencia','Valladolid','Vizcaya'," & _
                        "'Zamora','Zaragoza','Ceuta','Melilla');" & vbCrLf)
        sbScript.Append("var arrCodigos = new Array('01','02','03','04','05','06','07','08','09','10'," & _
                                                    "'11','12','13','14','15','16','17','18','19','20'," & _
                                                    "'21','22','23','24','25','26','27','28','29','30'," & _
                                                    "'31','32','33','34','35','36','37','38','39','40'," & _
                                                    "'41','42','43','44','45','46','47','48','49','50'," & _
                                                    "'51','52');" & vbCrLf)
        sbScript.Append("function provinciaCP(txt,lbl) {" & vbCrLf)
        sbScript.Append("var cp = String(txt).substring(0,2);" & vbCrLf)
        sbScript.Append("var ind, pos;" & vbCrLf)
        sbScript.Append("for(ind=0; ind<arrCodigos.length; ind++)" & vbCrLf)
        sbScript.Append("{" & vbCrLf)
        sbScript.Append("if (arrCodigos[ind] == cp)" & vbCrLf)
        sbScript.Append("break;" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append("pos = (ind < arrCodigos.length)? ind : -1;" & vbCrLf)
        sbScript.Append("if(arrProvincias[pos] != undefined)" & vbCrLf)
        sbScript.Append("{document.getElementById(lbl).innerHTML = arrProvincias[pos];}" & vbCrLf)
        sbScript.Append("else {document.getElementById(lbl).innerHTML = 'Provincia no identificada';}" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append("</script>" & vbCrLf)
        Me.Controls.Add(New LiteralControl(sbScript.ToString))
        '************************

        Me.Controls.Add(txt)
        Me.Controls.Add(New LiteralControl("&nbsp;"))
        Me.Controls.Add(lbl)
        txt.Attributes.Add("onChange", "provinciaCP(this.value,'" & lbl.ClientID & "');")
        Me.Controls.Add(New LiteralControl("<script>provinciaCP('" & txt.Text & "','" & lbl.ClientID & "');</script>"))
    End Sub

End Class
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #2 (permalink)  
Antiguo 16/04/2007, 11:13
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

He introducido una modificación, de modo que sólo permita la entrada de números:

Código:
        ...
        sbScript.Append("else {document.getElementById(lbl).innerHTML = 'Provincia no identificada';}" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append(vbCrLf)
        sbScript.Append("function soloNum(evt) {" & vbCrLf)
        sbScript.Append("var nav4 = window.Event ? true : false;" & vbCrLf)
        sbScript.Append("var key = nav4 ? evt.which : evt.keyCode;" & vbCrLf)
        sbScript.Append("return (key <= 13 || (key >= 48 && key <= 57) || key == 44);" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append("</script>" & vbCrLf)
        ...
        ...
        txt.Attributes.Add("onChange", "provinciaCP(this.value,'" & lbl.ClientID & "');")
        txt.Attributes.Add("OnKeyPress", "return soloNum(event)")
        Me.Controls.Add(New LiteralControl("<script>provinciaCP('" & txt.Text & "','" & lbl.ClientID & "');</script>"))
    End Sub
Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #3 (permalink)  
Antiguo 16/04/2007, 11:50
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

Por hoy ya dejo de incordiar. Los códigos postales han de tener 5 dígitos, por tanto:

Código:
sbScript.Append("if((arrProvincias[pos] != undefined) && (txt.length == 5))" & vbCrLf)
Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #4 (permalink)  
Antiguo 16/04/2007, 12:54
Avatar de xknown  
Fecha de Ingreso: diciembre-2004
Ubicación: Cusco - Perú
Mensajes: 2.248
Antigüedad: 20 años
Puntos: 7
Re: Control compuesto personalizado

Es mejor usar recursos embedidos en lugar de enviar directamente bloques de javascript, así se ahorra ancho de banda y es posible compartir la misma funcionalidad si existen varios controles del mismo tipo en una página determinada.

Saludos
__________________
Alex Concha
Buayacorp - Programación y Diseño
  #5 (permalink)  
Antiguo 17/04/2007, 01:17
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

Gracias xknown por tu respuesta. Lo que me comentas ya lo pensé, aunque no sabía cómo hacerlo. De hecho estuve estudiando varias maneras de crear los controles personalizados y esta es la que me resultó más sencilla. De todas formas, he probado ha poner varios controles en una misma página y no han habido conflictos, al menos en IE, lo cual no significa que no de problemas más adelante.

¿Cómo se incluirían los recursos embebidos?
¿Hay alguna manera de diseñar los controles como si fuera un control de usuario web, es decir, no tener que añadir los controles secundarios desde el código sino en modo diseño?

Gracias y un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #6 (permalink)  
Antiguo 17/04/2007, 15:48
Avatar de xknown  
Fecha de Ingreso: diciembre-2004
Ubicación: Cusco - Perú
Mensajes: 2.248
Antigüedad: 20 años
Puntos: 7
Re: Control compuesto personalizado

¿Qué versión del .NET Framework estás usando?

Saludos
__________________
Alex Concha
Buayacorp - Programación y Diseño
  #7 (permalink)  
Antiguo 18/04/2007, 00:33
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

Utilizo Visual Studio .Net 2003 con .Net Framework 1.1
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #8 (permalink)  
Antiguo 18/04/2007, 03:09
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

Una nueva modificación. Cuando se intenta acceder al texto introducido en el cuadro de texto desde el código de la página ASPX tenía que recurrir a esto:

Código:
CType(Me.CPEmpresa.FindControl(Me.CPEmpresa.IDTxt), TextBox).Text
Por lo que he añadido una nueva propiedad pública al control de manera que se pueda acceder fácilmente al valor del cuadro de texto tanto para leer como para modificar. El código completo quedaría ahora así:

Código:
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class controlCPProvincia
    : Inherits Control : Implements INamingContainer

    Private IDTxt As String = "TxtCP"
    Private _cpInicial As String

    Public Property CPInicial() As String
        Get
            Return _cpInicial
        End Get
        Set(ByVal Value As String)
            _cpInicial = Value
        End Set
    End Property

    Public Property Texto() As String
        Get
            Return CType(Me.FindControl(IDTxt), TextBox).Text
        End Get
        Set(ByVal Value As String)
            CType(Me.FindControl(IDTxt), TextBox).Text = Value
        End Set
    End Property

    Protected Overrides Sub CreateChildControls()
        Dim txt As New TextBox
        txt.MaxLength = "5"
        txt.Columns = "1"
        txt.ID = IDTxt
        txt.Text = CPInicial
        Dim lbl As New Label
        ......
De esta manera, símplemente en el código fuente de la página ASPX se pone:

Me.CPEmpresa.Texto

Lo único es que si hago un postback en la página no me conserva el texto de la etiqueta, apareciendo simpre el inicial "Provincia no identificada". No sé si es por el evento onload de javascript.

Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!

Última edición por Bravenap; 18/04/2007 a las 03:22
  #9 (permalink)  
Antiguo 18/04/2007, 04:21
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

Solucionado. Sí era un problema de javascript.

Código:
Me.Controls.Add(New LiteralControl("<script>provinciaCP('" & txt.Text & "','" & lbl.ClientID & "');</script>"))
Se cambia por esto otro:

Código:
Me.Controls.Add(New LiteralControl("<script>provinciaCP(document.getElementById('" & txt.ClientID & "').value,'" & lbl.ClientID & "');</script>"))
Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #10 (permalink)  
Antiguo 19/04/2007, 11:29
Avatar de xknown  
Fecha de Ingreso: diciembre-2004
Ubicación: Cusco - Perú
Mensajes: 2.248
Antigüedad: 20 años
Puntos: 7
Re: Control compuesto personalizado

Con respecto a la consulta que me hiciste,

- En asp.net 1.x, me parece que no puedes usar recursos embedidos como en asp.net 2, así que ese el código lamentablemente tiene que ir en un archivo aparte.
- Supongo que te refieres a esto no? http://msdn.microsoft.com/msdnmag/is...2/CuttingEdge/

Saludos
__________________
Alex Concha
Buayacorp - Programación y Diseño
  #11 (permalink)  
Antiguo 23/04/2007, 03:10
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 22 años, 1 mes
Puntos: 4
Re: Control compuesto personalizado

Gracias xknown por tus respuestas. De momento no me está generando ningún conflicto repetir el código Javascript cuando inserto más de un control en una misma página.

El artículo de Microsoft parece útil, aunque no lo he leido entero (me cuesta un poquito más entender las cosas en inglés, je je). No obstante he optado por algo más radical para acceder a los propiedades del cuadro de texto, tanto en tiempo de edición como de ejecución, que es hacer que el cuadro de texto se convierta como tal en una propiedad pública accesibel y modificable. De manera que no tengo que tener en cuenta todas las propiedades del cuadro de texto para posibilitar su acceso posterior.

Esta es la n-ésima modificación (y las que vendrán , tío pesao):
Código:
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class controlCPProvincia
    : Inherits Control : Implements INamingContainer

    Private IDTxt As String = "TxtCP"

    <Browsable(True), _
    Category("Controles secundarios"), _
    Description("Cuadro de texto para la introducción del código postal")> _
    Public ReadOnly Property CuadroTexto() As TextBox
        Get
            Return CType(Me.FindControl(IDTxt), TextBox)
        End Get
    End Property

    Protected Overrides Sub CreateChildControls()
        Dim txt As New TextBox
        txt.MaxLength = "5"
        txt.Columns = "5"
        txt.ID = IDTxt
        Dim lbl As New Label
        lbl.ID = "lbl" & IDTxt
        'Script con vectores*****
        Dim sbScript As New System.Text.StringBuilder
        sbScript.Append("<script language=javascript>" & vbCrLf)
        sbScript.Append("var arrProvincias = new Array(" & _
                        "'&Aacute;lava','Albacete','Alicante','Almer&iacute;a'," & _
                        "'&Aacute;vila','Badajoz','Baleares','Barcelona'," & _
                        "'Burgos','C&aacute;ceres','C&aacute;diz','Castell&oacute;n'," & _
                        "'Ciudad Real','C&oacute;rdoba','Coru&ntilde;a','Cuenca'," & _
                        "'Gerona','Granada','Guadalajara','Guip&uacute;zcoa'," & _
                        "'Huelva','Huesca','Ja&eacute;n','Le&oacute;n'," & _
                        "'L&eacute;rida','La Rioja','Lugo','Madrid'," & _
                        "'M&aacute;laga','Murcia','Navarra','Orense'," & _
                        "'Asturias','Palencia','Las Palmas','Pontevedra'," & _
                        "'Salamanca','Santa Cruz de Tenerife','Cantabria','Segovia'," & _
                        "'Sevilla','Soria','Tarragona','Teruel'," & _
                        "'Toledo','Valencia','Valladolid','Vizcaya'," & _
                        "'Zamora','Zaragoza','Ceuta','Melilla');" & vbCrLf)
        sbScript.Append("var arrCodigos = new Array('01','02','03','04','05','06','07','08','09','10'," & _
                                                    "'11','12','13','14','15','16','17','18','19','20'," & _
                                                    "'21','22','23','24','25','26','27','28','29','30'," & _
                                                    "'31','32','33','34','35','36','37','38','39','40'," & _
                                                    "'41','42','43','44','45','46','47','48','49','50'," & _
                                                    "'51','52');" & vbCrLf)
        sbScript.Append("function provinciaCP(txt,lbl) {" & vbCrLf)
        sbScript.Append("var cp = String(txt).substring(0,2);" & vbCrLf)
        sbScript.Append("var ind, pos;" & vbCrLf)
        sbScript.Append("for(ind=0; ind<arrCodigos.length; ind++)" & vbCrLf)
        sbScript.Append("{" & vbCrLf)
        sbScript.Append("if (arrCodigos[ind] == cp)" & vbCrLf)
        sbScript.Append("break;" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append("pos = (ind < arrCodigos.length)? ind : -1;" & vbCrLf)
        sbScript.Append("if((arrProvincias[pos] != undefined) && (txt.length == 5))" & vbCrLf)
        sbScript.Append("{document.getElementById(lbl).innerHTML = arrProvincias[pos];}" & vbCrLf)
        sbScript.Append("else {document.getElementById(lbl).innerHTML = 'Provincia no identificada';}" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append(vbCrLf)
        sbScript.Append("function soloNum(evt) {" & vbCrLf)
        sbScript.Append("var nav4 = window.Event ? true : false;" & vbCrLf)
        sbScript.Append("var key = nav4 ? evt.which : evt.keyCode;" & vbCrLf)
        sbScript.Append("return (key <= 13 || (key >= 48 && key <= 57) || key == 44);" & vbCrLf)
        sbScript.Append("}" & vbCrLf)
        sbScript.Append("</script>" & vbCrLf)
        Me.Controls.Add(New LiteralControl(sbScript.ToString))
        '************************

        Me.Controls.Add(txt)
        Me.Controls.Add(New LiteralControl("&nbsp;"))
        Me.Controls.Add(lbl)
        txt.Attributes.Add("onChange", "provinciaCP(this.value,'" & lbl.ClientID & "');")
        txt.Attributes.Add("OnKeyPress", "return soloNum(event)")
        Me.Controls.Add(New LiteralControl("<script>provinciaCP(document.getElementById('" & txt.ClientID & "').value,'" & lbl.ClientID & "');</script>"))
    End Sub

End Class
Gracias de nuevo por las respuestas. Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:13.