Problema con Objeto C#

Iniciado por Bob1098, 29 Diciembre 2014, 15:32 PM

0 Miembros y 1 Visitante están viendo este tema.

Bob1098

Hola, bueno estaba tratando de hacer un programilla en C# que sirviera para resolver sudokus, y de momento solo llevo hecho el cronometro de tiempo y los botones para controlar si comenzar, pausar o detener el juego. Para generar los números he pensado almacenarlos en una matriz int, y para mostrarlos pensé que sería mas cómodo utilizar una matriz de la clase TextBox en la que guardo todos los controles que tengo donde quiero mostrar los números, y asi con un ciclo for poder pasar de un textbox a otro sin problema.

La cuestión es que al darle valores a la propiedad Text de los TextBox almacenados en la matriz obtengo una excepción.

Código:
Código (cpp) [Seleccionar]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Sudoku
{
    public partial class Form1 : Form
    {
        byte s, m, h;
        bool paused = false;
        bool gameStarted = false;
        int[,] numeros = new int[9,9];
        TextBox[,] Numeros = new TextBox[9, 9];

        public Form1()
        {
            InitializeComponent();
        }

        private void UnirTextBox()
        {
            //Celda 1
            Numeros[0, 0] = nTextBox1;
            Numeros[0, 1] = nTextBox2;
            Numeros[0, 2] = nTextBox3;
            Numeros[1, 0] = nTextBox4;
            Numeros[1, 1] = nTextBox5;
            Numeros[1, 2] = nTextBox6;
            Numeros[2, 0] = nTextBox7;
            Numeros[2, 1] = nTextBox8;
            Numeros[2, 3] = nTextBox9;

            //Celda 2
            Numeros[0, 3] = nTextBox10;
            Numeros[0, 4] = nTextBox11;
            Numeros[0, 5] = nTextBox12;
            Numeros[1, 3] = nTextBox13;
            Numeros[1, 4] = nTextBox14;
            Numeros[1, 5] = nTextBox15;
            Numeros[2, 3] = nTextBox16;
            Numeros[2, 4] = nTextBox17;
            Numeros[2, 5] = nTextBox18;

            //Celda 3
            Numeros[0, 6] = nTextBox19;
            Numeros[0, 7] = nTextBox20;
            Numeros[0, 8] = nTextBox21;
            Numeros[1, 6] = nTextBox22;
            Numeros[1, 7] = nTextBox23;
            Numeros[1, 8] = nTextBox24;
            Numeros[2, 6] = nTextBox25;
            Numeros[2, 7] = nTextBox26;
            Numeros[2, 8] = nTextBox27;
        }

        private void GenerarNumeros()
        {
            Random rnd = new Random();
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    numeros[i, j] = rnd.Next(1, 9);
                    Numeros[i, j].Text = numeros[i, j].ToString(); //Aquí es el punto donde obtengo el error de ejecución.
                }
            }
        }

        private void Preparacion()
        {
            UnirTextBox();
            GenerarNumeros();
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            Preparacion();
            s = 1; m = 0; h = 0;
            timeTextBox.Text = "0:00:00";
            timer1.Start();
            gamePanel.Enabled = true;
            gameStarted = true;
        }

        private void pauseButton_Click(object sender, EventArgs e)
        {
            if (gameStarted)
            {
                if (!paused)
                {
                    timer1.Stop();
                    gamePanel.Enabled = false;
                    paused = true;
                }
                else
                {
                    timer1.Start();
                    gamePanel.Enabled = true;
                    paused = false;
                }
            }
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            gamePanel.Enabled = false;
            timeTextBox.Text = "0:00:00";
            s = 0; m = 0; h = 0;
            gameStarted = false;
        }

        private void checkButton_Click(object sender, EventArgs e)
        {

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (m < 10)
            {
                if (s < 10) timeTextBox.Text = h + ":" + "0" + m + ":" + "0" + s;
                else timeTextBox.Text = h + ":" + "0" + m + ":" + s;
            }
            else
            {
                if (s < 10) timeTextBox.Text = h + ":" + m + ":" + "0" + s;
                else timeTextBox.Text = h + ":" + m + ":" + s;
            }
            s++;
            if (s == 60)
            {
                s = 0;
                m++;
            }
            if (m == 60)
            {
                m = 0;
                h++;
            }
        }
    }
}


La excepción dice así:
Excepción no controlada del tipo 'System.NullReferenceException' en Sudoku.exe

Información adicional: Referencia a objeto no establecida como instancia de un objeto.

Espero que sepan a que se debe. Y ya de paso si conocen algún otro método para guardar los textbox que no sea manualmente como yo he hecho =P.

Shell Root

Printea las variables i, j en:
Código (csharp,8) [Seleccionar]
        private void GenerarNumeros()
       {
           Random rnd = new Random();
           for (int i = 0; i < 9; i++)
           {
               for (int j = 0; j < 9; j++)
               {
                   MessageBox.Show("i = " + i + " | j = " + j);
                   numeros[i, j] = rnd.Next(1, 9);
                   Numeros[i, j].Text = numeros[i, j].ToString(); //Aquí es el punto donde obtengo el error de ejecución.
               }
           }
       }
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

Eleкtro

#2
La excepción se produce por que intentas acceder a un objeto que no ha sido inicializado.

Comprueba si esto no te lanza una null-reference exception:
Código (vbnet) [Seleccionar]
Numeros(i, j) = new TextBox();
Numeros(i, j).Text = Convert.ToString(numeros(i, j));


Si te funciona, comprueba que nTextBox1 y siguientes están instanciados.

Saludos








Bob1098

Cita de: Eleкtro en 29 Diciembre 2014, 17:50 PM
La excepción se produce por que intentas acceder a un objeto que no ha sido inicializado.

Comprueba si esto no te lanza una null-reference exception:
Código (vbnet) [Seleccionar]
Numeros(i, j) = new TextBox();
Numeros(i, j).Text = Convert.ToString(numeros(i, j));


Si te funciona, comprueba que nTextBox1 y siguientes están instanciados.

Saludos

Si, ya no salta la excepción, pero no hace nada no se muestran los números. A que te refieres con instanciar los textbox? Tengo que hace nTextBox1 = new TextBox con todos? :S

El Benjo

Sí. Como menciona Elektro debes hacer eso con cada uno de los textbox (si pones atención al código verás que eso está resuelto porque la asignación está dentro del bucle for()). Recuerda que una variable del tipo de cualquier objeto (a diferencia de los tipos primitivos como int, bool, etc) es un puntero que guarda la dirección de memoria donde existen las propiedades del objeto. Cuando tú creas una variable de la forma:

Código (csharp) [Seleccionar]
TextBox VarObjeto;

La variable 'VarObjeto' no apunta a ninguna dirección de memoria. Y cuando haces:

Código (csharp) [Seleccionar]
VarObjeto = new TextBox();

Lo que haces es crear un nuevo objeto de la clase 'TextBox' y asignar a 'VarObjeto' la dirección de memoria donde reside el objeto.

Y eso de que no te muestre nada es porque al crear una nueva instancia para cada objeto del arreglo dejan de hacer referencia a los textbox que tienes creados en el formulario. Ahora, esto es lo interesante: Si previamente hacían referencia a los textbox que tienes en el formulario, ¿por qué te saltaba la excepción como si fueran objetos nulos? Espero que Elektro o alguien más nos pueda dar explicación a esto. :/
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

Bob1098

Cita de: El Benjo en 30 Diciembre 2014, 01:02 AM
Sí. Como menciona Elektro debes hacer eso con cada uno de los textbox (si pones atención al código verás que eso está resuelto porque la asignación está dentro del bucle for()). Recuerda que una variable del tipo de cualquier objeto (a diferencia de los tipos primitivos como int, bool, etc) es un puntero que guarda la dirección de memoria donde existen las propiedades del objeto. Cuando tú creas una variable de la forma:

Código (csharp) [Seleccionar]
TextBox VarObjeto;

La variable 'VarObjeto' no apunta a ninguna dirección de memoria. Y cuando haces:

Código (csharp) [Seleccionar]
VarObjeto = new TextBox();

Lo que haces es crear un nuevo objeto de la clase 'TextBox' y asignar a 'VarObjeto' la dirección de memoria donde reside el objeto.

Y eso de que no te muestre nada es porque al crear una nueva instancia para cada objeto del arreglo dejan de hacer referencia a los textbox que tienes creados en el formulario. Ahora, esto es lo interesante: Si previamente hacían referencia a los textbox que tienes en el formulario, ¿por qué te saltaba la excepción como si fueran objetos nulos? Espero que Elektro o alguien más nos pueda dar explicación a esto. :/

Efectivamente, es lo que tu dices al final de tu respuesta, no comprendo por qué motivo saltaba la excepción como si se tratasen de objetos nulos, si ya tenían asignada una dirección de memoria... Aún así gracias por las repsuestas a todos. :)