Stephen,
You are correct, it is to do with postbacks. What you need to remember is
that every time your page is loaded, your page class is recreated. This means
that any data stored in the class itself is recreated. No class data will
persist between page accesses (whether initial access or postback).
This will be the case with your addresses ArrayList.
To resolve the problem you need to:
1) create your empty ArrayList when the page is first loaded (i.e. when
IsPostBack = false) and add this empty ArrayList to one of the persisted
"bags" - see below.
2) when the button click handler fires, load the Array list back in from its
bag, add the new record to it, then save it back to its bag.
3) when the page is loaded after a postback (IsPostBack = true) you get the
ArrayList from the bag and assign it & DataBind to the datagrid.
Note that the ViewState bag works OK if only working on one page in your
application. If you want this data to be subsequently available to other
pages in your application, you can use the Session bag instead, which is
accessed in the same manner.
[Serializable]
protected class Address
{
private string _address1;
public string Address1
{
get{ return _address1; }
set{ _address1 = value; }
}
private string _address2;
public string Address2
{
get{ return _address2; }
set{ _address2 = value; }
}
// the rest ommitted to save RSI!
}
private void Page_Load(object sender, System.EventArgs e)
{
ArrayList addresses;
// when the page is first loaded only
if( !IsPostBack )
{
addresses = new ArrayList(5);
ViewState["Addresses"] = addresses;
}
// on subsequent PostBacks:
else
{
addresses = (ArrayList) ViewState["Addresses"];
if( addresses != null )
{
DataGrid1.DataSource = addresses;
DataGrid1.DataBind();
}
}
}
private void Button1_Click(object sender, System.EventArgs e)
{
ArrayList addresses;
addresses = (ArrayList) ViewState["Addresses"];
// note the above would usually be checked for null at this point
// or put in a try ... catch block. for now we let ASP provide
// an error page if anything is amiss.
Address newAddress = new Address();
newAddress.Address1 = this.TextBox1.Text.Trim();
newAddress.Address2 = this.TextBox2.Text.Trim();
// etc
addresses.Add(newAddress);
ViewState["Addresses"] = addresses;
DataGrid1.DataSource = addresses;
DataGrid1.DataBind();
//clear down the textboxes
this.TextBox1.Text = "";
this.TextBox2.Text = "";
// etc
}
Note from the above code that I have moved addresses into a local variable
that is retrieved from the bag wherever it is used. I find this helps avoid
confusion over the persistance of instance fields between method calls.
Hope this helps,
Chris.
"Stephen" wrote:
I have the following code working in order to create an array list and
populate a datagrid however everytime i click my button the first item in the
array and the first row in the datagrid are overwritten. I think this is some
sort of post back problem but i can't seem to figure out how to solve it. Can
someone help me with this please.
private ArrayList addresses;
private void Page_Load(object sender, System.EventArgs e)
{
if(!(ViewState["Addresses"]==null))
{
this.addresses = (ArrayList)ViewState["Addresses"];
}
else
{
this.addresses = new ArrayList();
}
}
private void Button1_Click(object sender, System.EventArgs e)
{
Address newAddress = new Address();
newAddress.Address1 = this.TextBox1.Text.Trim();
newAddress.Address2 = this.TextBox2.Text.Trim();
newAddress.Address3 = this.TextBox3.Text.Trim();
newAddress.Address4 = this.TextBox4.Text.Trim();
newAddress.Address5 = this.TextBox5.Text.Trim();
newAddress.Address6 = this.TextBox6.Text.Trim();
this.addresses.Add(newAddress);
//ViewState["Addresses"] = this.addresses;
this.DataGrid1.DataSource = this.addresses;
this.DataGrid1.DataBind();
//clear down the textboxes
this.TextBox1.Text = "";
this.TextBox2.Text = "";
this.TextBox3.Text = "";
this.TextBox4.Text = "";
this.TextBox5.Text = "";
this.TextBox6.Text = "";
this.TextBox1.Text = "";
}