使用动态生成的控件进行Gridview排序和分页

时间:2011-05-17 16:35:43

标签: c# asp.net sorting gridview dynamic-controls

我已经把自己变成了一个在网格中使用动态控件的腌菜。

我将gridview绑定到列表,然后添加dyanmic控件。为了保持控制状态,我需要在页面加载中执行此操作。但是,由于事件在页面加载后触发,我无法正确处理排序和分页事件。是否有任何创造性的解决方案可以解决这个问题,还是我错了?

编辑:我不确定我是否正确解释了我的问题。在生命周期中添加动态控件的位置无关紧要。问题是排序和分页事件需要重新绑定GridView,这显然导致分配给我的动态控件的属性从ViewState中丢失,因为排序和分页的绑定在生命周期的后期发生。

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();
}

4 个答案:

答案 0 :(得分:1)

嗯,我的答案是重新思考我是如何攻击这个问题的。我摆脱了动态链接按钮并添加了一个按钮字段。这样我就可以将gridview绑定到哪里,并且它的控制状态无关紧要。这是一个帮助我的页面。

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

答案 1 :(得分:0)

您应该在页面的PreRender事件中编写代码 ASP.NET Page Life Cycle Overview
在Page对象创建了呈现页面所需的所有控件(包括复合控件的子控件)之后引发的PreRender事件。

答案 2 :(得分:0)

您需要使用GridView的OnRowCreated事件来添加动态控件以便能够处理它们的状态。每次回发时,页面加载前以及每次在网格上调用OnRowCreated方法时都会自动触发DataBind()事件。

只有实际的数据绑定应该在OnRowDatabound事件中。

您也不应该每次回发都重新绑定网格。

答案 3 :(得分:0)

你错了,你必须从Page_Load()中删除这两行:

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

当我在控制器上绑定数据源时,我必须像这样覆盖OnInit并取两行并将其放在那里:

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

然后,它维护状态,因为它是在页面的ViewState初始化之前。正如托马斯所说,看看他给你的链接。

注意:对不起我的英语,我来自魁北克省,通常会说法语。