2011-05-17 48 views
3

我已经把自己变成了一个在网格中使用动态控件的泡菜。Gridview分类和分页动态生成控件

我将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(); 
} 
+0

检查此线程,它可能给你的想法http://stackoverflow.com/questions/5947780/how-to-convert-a-gridview-to-datatable-and-sort-the-datatable/5947912#5947912 – 2011-05-17 16:42:31

回答

1

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

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

0

你应该写你的代码页PreRender事件Page对象创造所需为了渲染页面的所有控件,包括复合控件的子控件后
ASP.NET Page Life Cycle Overview
PreRender引发的事件。

0

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

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

你也不应该在每次回发时重新绑定你的网格。

+0

我认为这是一个很好的建议,但是我添加到动态链接按钮的命令事件仍然不会触发,所以我不确定它是否解决了我的问题。除非我错过别的东西。 – plntxt 2011-05-17 17:27:41

+0

在我的特殊情况下,我需要这样做来为网格的每一列的标题添加一个自定义过滤器。我使用'OnRowCreated'事件来创建并添加一个DropDownList并为其添加一些过滤器值。当我以后需要添加排序时,我排序了数据源(不是网格本身),然后重新启动网格。 – 2011-05-17 17:53:19

0

你搞错了吧,你要删除的Page_Load这两条线路():

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

当我dinamicaly绑定数据源在我的控制,我必须重写像这样的OnInit,并采取两线,并把它有:

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

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

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