【问题标题】:Gridview Sorting and Paging with Dynamically Generated Controls使用动态生成的控件进行 Gridview 排序和分页
【发布时间】:2011-05-17 16:35:42
【问题描述】:

我在 gridivew 中使用动态控件让自己陷入了困境。

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

编辑:我不确定我是否正确解释了我的问题。在生命周期中添加动态控件的位置无关紧要。问题是排序和分页事件要求我重新绑定 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();
}

【问题讨论】:

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


【解决方案1】:

嗯,对我来说,答案是重新思考我是如何解决这个问题的。我摆脱了动态链接按钮并添加了一个按钮字段。这样我就可以将gridview绑定到任何地方,它的控制状态并不重要。这是一个帮助我的页面。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您的错误是您必须从 Page_Load() 中删除这两行:

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

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

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

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

        • 我认为这通常是一个很好的建议,但是我添加到动态链接按钮的命令事件仍然不会触发,所以我不确定它是否解决了我的问题。除非我错过了其他东西。
        • 在我的特殊情况下,我需要这样做以将自定义过滤器添加到网格每列的标题中。我使用OnRowCreated 事件来创建和添加一个 DropDownList 并向其中添加一些过滤器值。当我后来需要添加排序时,我对数据源(不是网格本身)进行排序,然后重新绑定网格。
        猜你喜欢
        • 1970-01-01
        • 2010-10-16
        • 1970-01-01
        • 1970-01-01
        • 2012-11-29
        • 1970-01-01
        • 2012-08-23
        • 2012-03-14
        • 2015-08-11
        相关资源
        最近更新 更多