Cityonhill93
Cityonhill93

Reputation: 83

Taking values into an array of textboxes (ASP.NET using C#)

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"]);
}  

}

Upvotes: 0

Views: 4894

Answers (3)

Andrew Savinykh
Andrew Savinykh

Reputation: 26329

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.

Upvotes: 0

findcaiyzh
findcaiyzh

Reputation: 647

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

Upvotes: 1

pete
pete

Reputation: 25091

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.

Upvotes: 0

Related Questions