views:

616

answers:

2

Hi, I have the following code

Imports System.Data

Partial Class Students_AddWishes Inherits System.Web.UI.Page

Public dt As New DataTable



Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    dt.Columns.Add("ID", System.Type.GetType("System.Int32"))
    dt.Columns.Add("univirsity", System.Type.GetType("System.Int32"))
    dt.Columns.Add("major", System.Type.GetType("System.Int32"))





End Sub



Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.Click

    Dim row1 As DataRow = dt.NewRow()
    row1("ID") = dt.Rows.Count + 1
    row1("univirsity") = ddlUnivs.SelectedValue
    row1("major") = ddlMajors.SelectedValue
    dt.Rows.Add(row1)
    GridView1.DataSource = dt
    GridView1.DataBind()




End Sub

End Class

the problem is it shows only one row or record. How to make it shows many records?

+2  A: 

Your page load event you are not checking if it is a post back:

 If Not IsPostBack Then
     'process code if it is not a post back
 End If

Everytime you click the btnAdd button your page does a post back to the server.

I just noticed that you probably are not understanding the life time of an object.

You had done this in your code:

Public dt As New DataTable 

The problem with that is you have defined this is a class variable and once the page has loaded you have an instance of type dt that may have some columns associated with it. But as soon as you record an event such as a button click that reference is destroyed and a new dt is created.

You will have to make some use of session variables or a database to store the state of dt.

Here is an example in C#:

 protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ID", System.Type.GetType("System.Int32"));
            dt.Columns.Add("univirsity", System.Type.GetType("System.Int32"));
            dt.Columns.Add("major", System.Type.GetType("System.Int32"));
            Session["MyDataTable"] = dt;
        }
    }

    protected void btnAdd_Click(object sender, EventArgs e)
    {
        DataTable t = (DataTable)Session["MyDataTable"];
        DataRow row1 = t.NewRow();

        row1["ID"] = t.Rows.Count + 1;
        row1["univirsity"] = 3;
        row1["major"] = 31;
        t.Rows.Add(row1);

        Session["MyDataTable"] = t;
        GridView1.DataSource = t;
        GridView1.DataBind(); 
    }

And the same code in vb.net:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) 
    If Not Page.IsPostBack Then 
        Dim dt As New DataTable() 
        dt.Columns.Add("ID", System.Type.[GetType]("System.Int32")) 
        dt.Columns.Add("univirsity", System.Type.[GetType]("System.Int32")) 
        dt.Columns.Add("major", System.Type.[GetType]("System.Int32")) 
        Session("MyDataTable") = dt 
    End If 
End Sub 

Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As EventArgs) 
    Dim t As DataTable = DirectCast(Session("MyDataTable"), DataTable) 
    Dim row1 As DataRow = t.NewRow() 

    row1("ID") = t.Rows.Count + 1 
    row1("univirsity") = 3 
    row1("major") = 31 
    t.Rows.Add(row1) 

    Session("MyDataTable") = t 
    GridView1.DataSource = t 
    GridView1.DataBind() 
End Sub 

So now what the code does is instantiate a new datatable object as long as we are on the page (first post back) and adds the columns. Once it has defined the data table we throw it in some session state. When you click the add button you cannot in your previous code just keep using dt because dt scope was lost in your prior code. We do this by assigning the sessioned datatable which was stored prior to a temp datatable. We add the row and reset the session that way the next time we add a row it will display the second row, then third row, and so on...

I recommend a good asp.net book on such as Beginning ASP.net 3.5 in C# 2008. There are a ton of vb.net books on the same subject matter.

JonH
Thanks that was very helpful
Fahad
A: 

Hey,

You need to save the datatable to Session, because local variables are not preserved. So you need to do:

protected override OnLoad(..) //or OnInit
{
   dt = Session["DataTable"] as DataTable;
   if (dt == null)
   {
       dt = new DataTable();
       //load columns
   }
}

protected override OnUnLoad(..)
{
   Session["DataTable"] = dt;
}

Session saves the data table reference across postbacks as the web is stateless.

Brian
I would not store a DataTable in Session, as you're basically storing it in memory on the server. What happens if you application is load balanced across multiple servers? What happens if the table grows to be larger than x number of rows or you have y number of users above what you have today?
dustinupdyke
That's what JonH's solution does too; you have to store it somewhere, or reload from the database on every page load; unfortunately, a global variable does not retain any of its values so it is essentially lost every time.... but loading from DB or using cache or other data store (disk io like XMl file) are all viable options too... session isn't the only solution, just one often chosen because it's user-specific. And you are right, multiple servers is an issue too... so you have to figure out the right solution.
Brian
@dustinupdyke - there is nothing wrong for this particular example to store this in a session. I assume you read the question it is quite basic. Of course if your app is going to be load balanced that is an entirely different question in and of itself. One can write up their own custom caching mechanism. In the end, you have to know what to choose. The originator of this post is not looking for anything high level and session works perfectly fine in this case.
JonH
@JonH I read the question, thanks. My point is that examples become someone's baseline if that is all they know. In most production environments, you would not use Session, so why propagate its use through examples?
dustinupdyke
Why wouldn't you use session? Most apps aren't load balanced against multiple servers, so Session is a perfectly valid storage mechanism.
Brian
@dustinupdyke - we run a ton of production apps that use session, that just doesn't make sense.
JonH
What happens to your users when the app pool resets? When the server runs out of memory? When the network team decides to load balance the app? I would not be putting DataTables in Session, period, and I would not be propagating the idea with examples.
dustinupdyke