简体   繁体   中英

Gridview Sorting and Paging with Dynamically Generated Controls

I've gotten myself into a pickle with using dynamic controls in a gridivew.

I am binding the gridview to a list and am then adding dyanmic controls. IN order to keep the control state I need to do this in page load. However since events fire after page load I am unable to properly handle sorting and paging events. Are there any creative solutions to this problem or am I going about this all wrong?

protected void Page_Load(object sender, EventArgs e)
{       
   //NOTE: to maintain control state of dynamic controls all databinding needs to be done in page load. 
   grdProducts.DataSource = GetDataSource();
   grdProducts.DataBind();
}

protected void grdProducts_OnRowDatabound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType != DataControlRowType.DataRow) return;        

    ManufacturerProduct m = new ManufacturerProduct();

    m.Model = DataBinder.Eval(e.Row.DataItem, "Model").ToString();

    PlaceHolder ph = new PlaceHolder();        
    ph = (PlaceHolder)e.Row.FindControl("phAddToCart");        

    LinkButton lb = new LinkButton();
    lb.Text = "Add To Cart";
    //NOTE: if I bind after page load the command never fires.      
    lb.Command +=  new CommandEventHandler(AddItem);
    lb.CommandName = "AddItem";
    lb.CommandArgument = m.Model;        
    ph.Controls.Add(lb);

}

protected void grdProducts_OnSorting(object sender, GridViewSortEventArgs e)
{
    //NOTE: since events fire after page load I can't handle this properly.

    hfSortExpression.Value = e.SortExpression.ToString();

    grdProducts.PageIndex = 0;
    //NOTE: If I rebind here I hose my dynamic controls
    //grdProducts.DataSource = GetDataSource();
    //grdProducts.DataBind();
}

Well, the answer for me was to rethink how I attacked the problem. I got rid of the dynamic linkbutton and added a button field instead. That way I could bind the gridview where ever and its control state didn't matter. Here is a page that helped me.

http://msdn.microsoft.com/en-us/library/bb907626.aspx

You should write your code in PreRender event of page
ASP.NET Page Life Cycle Overview
PreRender event raised after the Page object has created all controls that are required in order to render the page, including child controls of composite controls.

You need to use the OnRowCreated event of the GridView for adding dynamic controls to be able to handle state of them. The OnRowCreated event is fired automatically at every postback, before page load and everytime you call the DataBind() method on the grid.

Only the actual databinding should be in the OnRowDatabound event.

You should also not rebind your grid every postback.

Your mistake it that you have to remove these two lines from Page_Load() :

grdProducts.DataSource = GetDataSource();
grdProducts.DataBind();

When I dinamicaly bind datasource on my control, I must override the OnInit like this and take the two line and put it there :

protected override void OnInit(EventArgs e) {
   grdProducts.DataSource = GetDataSource();
   grdProducts.DataBind();
   base.OnInit(e);
}

Then, it maintains states because it's before the initialisation of the ViewState of the page. As Thomas said, get a look at the links he gave you.

Note : Sorry for my english, I'm from Quebec and usualy talk french.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM