0

So I have an array of textboxes dynamically appear (The number of textboxes depends upon how a number from a database). They draw to the screen just fine.

    i = 0;

    while (i < size)
    {
        pnlTxtBoxes.Controls.Add(labels[i]);
        pnlTxtBoxes.Controls.Add(txtBoxes[i]);
        pnlTxtBoxes.Wrap = true;
        i++;
    }

Like I said, the textboxes appear and the labels are displaying correctly. But when I go to retrieve the text from them, I get the error "Object reference not set to an instance of an object."

    i = 0;

    while (i < size)
    {
        values[i] = txtBoxes[i].Text;
        txtBoxes[i].Visible = false;
        labels[i].Visible = false;
        i++;
    } 

Does anybody have an idea as to why I'm getting this error (and what I can do to fix it)?

EDIT: Here is all of the code. This is just a development DB, so I am not worried about showing the password

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MySql.Data.MySqlClient;

public partial class dieClearanceCalc : System.Web.UI.Page
{
static string connectionString = "database=localhost;database=matedevdb;uid=dev;pwd=123;";
MySqlConnection con = new MySqlConnection(connectionString);
MySqlCommand cmd = new MySqlCommand("SELECT shapeName FROM tblShapes;");
MySqlDataReader reader;
int size;
TextBox[] txtBoxes;
Label[] labels;

protected void Page_Load(object sender, EventArgs e)
{
    cmd.Connection = con;
    try
    {
        con.Open();
        reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            shapeSelection.Items.Add(reader.GetString(0));
        }
        reader.Close();
    }
    catch (Exception ex)
    {
        Response.Write("<p style='Color:red'>Error:<br/>" + ex + "</p>");
    }
}
protected void shapeSelected(object sender, EventArgs e)
{
    string[] labelTxt;
    int i = 0;

    //Make current elements invisable
    lblShape.Visible = false;
    shapeSelection.Visible = false;
    btnSelectShape.Visible = false;

    // find the size of the arrays
    cmd.CommandText = "SELECT COUNT(varID) FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
    reader = cmd.ExecuteReader();
    if (reader.Read())
    {
        size = reader.GetInt32(0);
    }
    reader.Close();

    labelTxt = new string[size];
    labels = new Label[size];
    txtBoxes = new TextBox[size];

    // gather the labels from the db
    cmd.CommandText = "SELECT varDesc FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
    reader = cmd.ExecuteReader();

    i = 0;

    while (reader.Read())
    {
        labelTxt[i] = reader.GetString("varDesc");
        i++;
    }
    reader.Close();

    i = 0;

    while (i < size)
    {
        labels[i] = new Label();
        txtBoxes[i] = new TextBox();
        labels[i].Text = labelTxt[i];
        i++;
    }

    i = 0;

    while (i < size)
    {
        pnlTxtBoxes.Controls.Add(labels[i]);
        pnlTxtBoxes.Controls.Add(txtBoxes[i]);
        pnlTxtBoxes.Wrap = true;
        i++;
    }

    btnSendData.Visible = true;
    //Response.Write(size); test to see if the size variable is working
    Response.Write(size);

}

protected void calc(object sender, EventArgs e)
{
    //declarations  
    formula diagonal, periphery;
    string dFormula = "", pFormula = "";
    string[] variables;
    string[] values;
    int i = 0;
    //end of declarations

    // This value must be retrievd again, because somewhere size is getting a value of  0
    cmd.CommandText = "SELECT COUNT(varID) FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
    reader = cmd.ExecuteReader();
    if (reader.Read())
    {
        size = reader.GetInt32(0);
    }
    reader.Close();


    variables = new string[size];
    values = new string[size];

    i = 0;

    while (i < size)
    {
        values[i] = txtBoxes[i].Text;
        txtBoxes[i].Visible = false;
        labels[i].Visible = false;
        i++;
    }

    btnSendData.Visible = false;

    // retrieve the diagonal formula from the db
    cmd.CommandText = "SELECT diagonalFormula, peripheryFormula FROM tblShapes WHERE shapeName='" + shapeSelection.SelectedValue + "'";
    reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        dFormula = reader.GetString("diagonalFormula");
        pFormula = reader.GetString("peripheryFormula");
    }
    reader.Close();

    Response.Write(size);

    // gather the variable names from the db
    cmd.CommandText = "SELECT varName FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
    reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        variables[i] = reader.GetString("varName");
        i++;
    }
    reader.Close();

    con.Close();

    diagonal = new formula(dFormula, variables, values);
    periphery = new formula(pFormula, variables, values);

    txtDiagonal.Visible = true;
    txtPeriphery.Visible = true;

    txtDiagonal.Text = diagonal.getEquation();
    txtPeriphery.Text = periphery.getEquation();
}

public static double Evaluate(string expression)
{
    System.Data.DataTable table = new System.Data.DataTable();
    table.Columns.Add("expression", string.Empty.GetType(), expression);
    System.Data.DataRow row = table.NewRow();
    table.Rows.Add(row);
    return double.Parse((string)row["expression"]);
}  

}

4
  • Which line of code is it complaining about specifically? Commented Feb 15, 2012 at 2:33
  • where did you define values ? There's a lot of relevant code missing here Commented Feb 15, 2012 at 2:37
  • 1
    asp.net pages have their life cycle. The controls and variables of the page will be recreated when loading. Please give us more details, such as which method your code is located in. Commented Feb 15, 2012 at 2:55
  • It is complaining about the line values[i] = txtBoxes[i].Text; Commented Feb 15, 2012 at 3:02

3 Answers 3

1

I reckon you initialize the labels and txtBoxes in if IsPostBack block and don't save it in ViewState or Session.

Edit: saw your code labels and txtBoxes was initialized in shapeSelected method. same problem will happen: they are lost between postback.

So they are empty in event handler when postback because whole Page object was re-created when postback. Asp.net runtime helps to load content from ViewState for control.But for class member variable you have to maintain by yourself.like:

public string NavigateUrl
{
  get
  {
    string text = (string) ViewState["NavigateUrl"];
    if (text != null)
       return text;
    else
       return string.Empty;
  }
  set
  {
    ViewState["NavigateUrl"] = value;
  }
}

Above code comes from:
Understanding ASP.NET View State
http://msdn.microsoft.com/en-us/library/ms972976.aspx
The article also introduces View State and Dynamically Added Controls

Sign up to request clarification or add additional context in comments.

Comments

0

An important thing to remember when programming with ASP.NET is that your whole object model on a page gets created with every web request again and again. This means that if you add some controls to you page dynamically in an event that does not happen each page load they are not going to survive the postback if you don't add them again somehow.

You can read about Asp.Net page Life Cycle here: http://msdn.microsoft.com/en-us/library/ms178472.aspx

I don't think there is a standard way to solve your problem, but what you are trying to do can be achieved in several ways. One was already mentioned to you - usage of ViewState. Another one would be hitting database on each post back, and making sure you are recreating the controls each time the page is served. One more way is to somehow encode the data that is required for recreating your controls and make sure that they are passed with each post back. The latter is essentially what ViewState does, but you can do it more efficiently if you want to reduce the size of you ViewState, and thus size in bytes of your postback and page.

Comments

0

Without seeing more code, I can only guess that the problem lies with where you populate the txtBoxes[] array. Make sure there are no null values in that array.

3 Comments

The fact that controls appear on the page correctly indicates that the relevant values are not nulls.
When rendering the controls, sure... what about on postback when this is likely occurring (e.g., after the user has entered data in them)? That's why I'm asking how is the array built .
@findcaiyzh has the correct answer. The variables need to be stored in viewstate and then retrieved on postback. (+1 to @findcaiyzh!).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.