所以我有一组动态显示的文本框(文本框的数量取决于数据库中的数字的方式)。他们画得很好。
i = 0;
while (i < size)
{
pnlTxtBoxes.Controls.Add(labels[i]);
pnlTxtBoxes.Controls.Add(txtBoxes[i]);
pnlTxtBoxes.Wrap = true;
i++;
}
就像我说的那样,文本框出现并且标签正确显示。但是当我从它们中检索文本时,我收到错误“对象引用未设置为对象的实例。”
i = 0;
while (i < size)
{
values[i] = txtBoxes[i].Text;
txtBoxes[i].Visible = false;
labels[i].Visible = false;
i++;
}
有没有人知道为什么我会收到这个错误(我可以做些什么来修复它)?
编辑:这是所有代码。这只是一个开发数据库,所以我不担心显示密码
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"]);
}
}
答案 0 :(得分:1)
我认为如果IsPostBack阻止你初始化标签和txtBox,并且不将它保存在ViewState或Session中。
修改强> 看到你的代码标签和txtBoxes在shapeSelected方法中初始化。同样的问题会发生:它们在回发之间丢失。
因此在回发时它们在事件处理程序中是空的,因为在回发时重新创建了整个Page对象。 Asp.net运行时有助于从ViewState加载内容以进行控制。但对于类成员变量,您必须自己维护。喜欢:
public string NavigateUrl
{
get
{
string text = (string) ViewState["NavigateUrl"];
if (text != null)
return text;
else
return string.Empty;
}
set
{
ViewState["NavigateUrl"] = value;
}
}
以上代码来自:
了解ASP.NET视图状态
http://msdn.microsoft.com/en-us/library/ms972976.aspx
本文还介绍了视图状态和动态添加控件
答案 1 :(得分:0)
如果没有看到更多代码,我只能猜测问题在于填充txtBoxes[]
数组的位置。确保该数组中没有空值。
答案 2 :(得分:0)
使用ASP.NET编程时要记住的一件重要事情是,页面上的整个对象模型会一次又一次地创建每个Web请求。这意味着如果您在每次加载不发生的事件中动态地向页面添加一些控件,如果您不以某种方式再次添加它们,它们将无法在回发中存活。
您可以在此处阅读有关Asp.Net页面生命周期的内容:http://msdn.microsoft.com/en-us/library/ms178472.aspx
我认为没有一种标准方法可以解决您的问题,但您尝试做的事情可以通过多种方式实现。已经提到过一个 - 使用ViewState。另一个是在每个帖子上回击数据库,并确保每次提供页面时都重新创建控件。另一种方法是以某种方式编码重新创建控件所需的数据,并确保它们随每个帖子一起传递。后者基本上是ViewState的功能,但是如果你想减小ViewState的大小,那么你可以更有效地做到这一点,从而缩小你的回发和页面的大小。