none
NullReferenceException en UserControl RRS feed

  • Pregunta

  • Hola, he creado un UserControl muy sencillo con un par de TextBox y necesito agregarlo a un TabPage que esta contenido dentro de otro y usando el siguiente código me da error por referencia nula al agregarlo al TabPage.

            Dim MyControl As New TimerPanel
            With MyControl
                .Name = "Timer0"
                .NombreTimerTxt.Text = "Timer Control"
                .TimerBox.Text = "Timer 00"
            End With
            Me.TabControl3.TabPages("Timers").Controls.Add(MyControl) '<-Aquí da NullReferenceException
            Dim Ubicacion As Point
            Ubicacion.X = 4
            Ubicacion.Y = 1
            Me.TabControl3.TabPages("Timers").Controls("Timer0").Location = Ubicacion

    El IDE me dice que use New pero ya lo hice en la primera linea. No entiendo que estoy haciendo mal.

    Otro tema, si quisiera agregar 15 controles del mismo tipo a la misma TabPage ¿Bastaría con iterar este código y modificar las coordenadas y el nombre del control?


    The Real Blue


    viernes, 4 de abril de 2014 13:42

Respuestas

  • Con el debugger, examina cada una de las partes de la sentencia que te da error, a ver cuál de ellas es Nothing. Mi sospecha es que puede ser que Me.TabControl3.TabPages("Timers") devuelva Nothing. Eso ocure si la pestaña Timers no existe. Y la causa de que no exista podría ser que ese fragmento de código lo estés ejecutando antes de que se haya inicializado la pestaña del TabControl (o que el nombre esté mal escrito y no se llame realmente "Timers"). Pero no se puede saber a simple vista solo con examinar ese fragmento de código. Tendrás que seguir la ejecución paso a paso con el debugger y comprobar si pasa o no pasa por la inicialización, y qué está devolviendo cada parte de la sentencia que falla.

    Y sí, para añadir 15 controles basta con poner un bucle que vaya creando instancias y añadiéndolos a la colección Controls.

    viernes, 4 de abril de 2014 17:48
  • [...] estoy viendo como hacer para obtener el valor de cada TextBox que contiene cada UserControl agregado dinamicamente.

    Creo que había hecho algo similar y reinstanciando y llamando de la misma forma el control se podía modificar el control gemelo.

    Lo de "llamar de la misma forma al control" creo que lo estás confundiendo con los arrays de controles que se podían crear en VB6 y anteriores. En VB.NET el mecanismo es distinto. Necesitarás guardar una referencia a cada uno de los controles que has añadido para llamar a los métodos y propiedades de dicho control. Una forma de conservarlas es crear un array de controles, y dentro del bucle que los va instanciando, copiar la referencia desde el bucle al array para luego poderla usar. La otra alternativa es buscar la referencia dentro de la propia colección "Controls" en donde antes añadiste cada uno de los controles.

    Una vez que tengas la referencia, en principio podrías usarla para acceder al textbox si le pones accesibilidad pública. Pero en general esto se considera poco elegante; es preferible que el textbox lo dejes privado dentro del usercontrol que lo contiene y que expongas su contenido mediante una propiedad pública, que sería la que llamarías a través de la referencia del control.

    domingo, 6 de abril de 2014 6:42

Todas las respuestas

  • Con el debugger, examina cada una de las partes de la sentencia que te da error, a ver cuál de ellas es Nothing. Mi sospecha es que puede ser que Me.TabControl3.TabPages("Timers") devuelva Nothing. Eso ocure si la pestaña Timers no existe. Y la causa de que no exista podría ser que ese fragmento de código lo estés ejecutando antes de que se haya inicializado la pestaña del TabControl (o que el nombre esté mal escrito y no se llame realmente "Timers"). Pero no se puede saber a simple vista solo con examinar ese fragmento de código. Tendrás que seguir la ejecución paso a paso con el debugger y comprobar si pasa o no pasa por la inicialización, y qué está devolviendo cada parte de la sentencia que falla.

    Y sí, para añadir 15 controles basta con poner un bucle que vaya creando instancias y añadiéndolos a la colección Controls.

    viernes, 4 de abril de 2014 17:48
  • Ese era parte del problema, estaba con otro nombre, le había puesto Timer solo a la propiedad Text y no a la propiedad name, así que la renombre a "TimersTab" y luego solo agregue el control de la siguiente forma

    TimersTab.Controls.Add(MyControl)

    .Ahora ya lo tengo andando, y estoy viendo como hacer para obtener el valor de cada TextBox que contiene cada UserControl agregado dinamicamente.

    Creo que había hecho algo similar y reinstanciando y llamando de la misma forma el control se podía modificar el control gemelo.

    ¿Que opina?


    The Real Blue

    viernes, 4 de abril de 2014 19:16
  • [...] estoy viendo como hacer para obtener el valor de cada TextBox que contiene cada UserControl agregado dinamicamente.

    Creo que había hecho algo similar y reinstanciando y llamando de la misma forma el control se podía modificar el control gemelo.

    Lo de "llamar de la misma forma al control" creo que lo estás confundiendo con los arrays de controles que se podían crear en VB6 y anteriores. En VB.NET el mecanismo es distinto. Necesitarás guardar una referencia a cada uno de los controles que has añadido para llamar a los métodos y propiedades de dicho control. Una forma de conservarlas es crear un array de controles, y dentro del bucle que los va instanciando, copiar la referencia desde el bucle al array para luego poderla usar. La otra alternativa es buscar la referencia dentro de la propia colección "Controls" en donde antes añadiste cada uno de los controles.

    Una vez que tengas la referencia, en principio podrías usarla para acceder al textbox si le pones accesibilidad pública. Pero en general esto se considera poco elegante; es preferible que el textbox lo dejes privado dentro del usercontrol que lo contiene y que expongas su contenido mediante una propiedad pública, que sería la que llamarías a través de la referencia del control.

    domingo, 6 de abril de 2014 6:42