protected void btnLoadData_Click(object sender, EventArgs e) { GridView1.DataSource = LoadData(); GridView1.DataBind(); GridView1.EnableViewState = true; }
Here the LoadData() method is loading a simple list of objects into a GridView. This could be loading data from a database, a file, or pretty much anywhere. This will load the GridView just fine and everything will render to the page as you would expect.

The problem comes when we cause another postback to happen on the page. If we click our Search button in the image above without making any code changes our result is not at all what we want.

So how do we go about fixing this? The easiest way I've found is to create a Session backed property to store the data in. Then in the page's PreLoad event we can check to see if that property is null or not. If the property is not null then we set it as the datasource for our control and rebind the control.
public List<Employee> Employees { get { object temp = Session["Employees"]; return temp == null ? null : (List<Employee>)temp; } set { Session["Employees"] = value; } }
I am using a simple list of objects here but you can just as easily use a DataTable or some other collection type. Now we can modify our original button load code a little bit to make use of our new property. At the same time we should also add the PreLoad event to our page and make sure that we are rebinding our data on each postback. The PreLoad event is a good choice for this because at this point all of our controls and their ViewState have been loaded.
protected void Page_PreLoad(object sender, EventArgs e) { if (Employees != null) { GridView1.DataSource = Employees; GridView1.DataBind(); } } protected void btnLoadData_Click(object sender, EventArgs e) { Employees = LoadData(); GridView1.DataSource = Employees; GridView1.DataBind(); GridView1.EnableViewState = true; }
Now we have dynamically loaded data that we can work with across multiple postbacks.