如何获取总行数以及为什么GridView DataSource属性在DataBound事件处理程序中为null?

问题描述 投票:0回答:1

我想在GridView数据绑定事件处理程序中获取总行数,所以我尝试了以下方法:

   protected void grid_DataBound(object sender, EventArgs e)
   {
       GridView grid = (GridView)sender;
       DataSet data = grid.DataSource as DataSet;
       if (data == null)
         return;
       int totalRows = data.Tables[0].Rows.Count;
   }

问题是grid.DataSource属性为null。 DataSourceID属性不为null,这是否意味着我无法访问DataBound事件处理程序中的DataSource对象,除非我直接分配DataSource属性?

编辑

这是我的GridHelper类中用于将rowcount添加到BottomPagerRow的代码。我想摆脱传递ObjectDataSource的要求,但不能,因为我需要使用Selected事件来获取总行数。因此问题的原因。

我也认为在自定义控件中可能会更好,我可以访问ViewState,和/或在Init事件期间创建子控件(我仍然有一个问题需要通过寻呼机使用额外单元格渲染的方式来解决),但后来我当数据源本身似乎在任何GridView事件中都不可用时,仍然存在如何获得总行数的问题。

编辑2与特定问题不太相关,但我解决了寻呼机渲染时遇到的问题,所以我更新了发布的代码。我在这里找到了诀窍:http://michaelmerrell.com/2010/01/dynamically-modifying-the-asp-net-gridview-paging-control/

#region Fields
private int totalRows = -1;
#endregion

#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="GridHelper"/> class.
/// Adds EventHandlers to the GridView to display results from the ObjectDataSource in the footer.
/// Marked as obsolete because AddResultsToFooter method provides a static access to the same functionality
/// An instance of GridHelper is required by the passed in GridView to store the totalRows value between the two event handlers
/// </summary>
/// <param name="grid">The grid.</param>
/// <param name="source">The ObjectDataSource linked to the GridView.</param>
[Obsolete("Use AddResultsToFooter instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public GridHelper(GridView grid, ObjectDataSource source)
{
    source.Selected += source_Selected;
    grid.PreRender += grid_PreRender;
}
#endregion

#region Event Handlers

private void grid_PreRender(object sender, EventArgs e)
{
    GridView grid = (GridView)sender;

    if (grid.HeaderRow != null)
        grid.HeaderRow.TableSection = TableRowSection.TableHeader;

    //Add a cell to the bottom pager row to display the total results
    if (grid.BottomPagerRow == null || !grid.BottomPagerRow.Visible)
        return;

    //Get the control used to render the pager
    //http://michaelmerrell.com/2010/01/dynamically-modifying-the-asp-net-gridview-paging-control/
    Table tblPager = grid.BottomPagerRow.Cells[0].Controls[0] as Table;
    if (tblPager == null)
        return;

    if (totalRows < 0)
    {
        //The DataSource has not been refreshed so get totalRows from round trip to client
        addResultsToPagerTable(tblPager, grid.Attributes["results"]);
        return;
    }

    int firstRow = grid.PageIndex * grid.PageSize + 1;
    int lastRow = firstRow + grid.Rows.Count - 1;

    string results;
    if (totalRows <= grid.PageSize)
        results = string.Format("<span class='grid-pager'>{0} Results</span>", totalRows);
    else
        results = string.Format("Results <b>{0}</b> to <b>{1}</b> of <b>{2}</b>", firstRow, lastRow, totalRows);

    addResultsToPagerTable(tblPager, results);

    //Need to store the information somewhere that is persisted via ViewState, and we don't have access to ViewState here
    grid.Attributes.Add("results", results);
}

/// <summary>
/// Handles the Selected event of the source control. Gets the total rows, since it is not possible to access them from the GridView.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Web.UI.WebControls.ObjectDataSourceStatusEventArgs"/> instance containing the event data.</param>
private void source_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
    if (e.ReturnValue is DataView)
        totalRows = ((DataView)e.ReturnValue).Count;
    else if (e.ReturnValue is EntitySet)
        totalRows = ((EntitySet)e.ReturnValue).Count;
}
#endregion

#region Private Methods
private static void addResultsToPagerTable(Table tblPager, string results)
{
    //http://michaelmerrell.com/2010/01/dynamically-modifying-the-asp-net-gridview-paging-control/

    //Get a handle to the original pager row
    TableRow pagesTableRow = tblPager.Rows[0];

    //Add enough cells to make the pager row bigger than the label we're adding
    while (pagesTableRow.Cells.Count < 10)
        pagesTableRow.Cells.Add(new TableCell { BorderStyle = BorderStyle.None });

    //Add a new cell in a new row to the table
    TableRow newTableRow = new TableRow();
    newTableRow.Cells.AddAt(0, new TableCell
    {
        Text = results,
        BorderStyle = BorderStyle.None,
        ColumnSpan = pagesTableRow.Cells.Count
    });

    tblPager.Rows.AddAt(0, newTableRow);

}
#endregion

#region Public Methods
/// <summary>
/// Adds EventHandlers to the GridView to display results from the ObjectDataSource in the footer.
/// </summary>
/// <param name="grid">The GridView.</param>
/// <param name="source">The ObjectDataSource linked to the GridView.</param>
public static void AddResultsToFooter(GridView grid, ObjectDataSource source)
{
    if (grid == null)
        throw new ArgumentNullException("grid", "grid is null.");
    if (source == null)
        throw new ArgumentNullException("source", "source is null.");

    new GridHelper(grid, source);
}
#endregion
asp.net data-binding gridview datasource
1个回答
0
投票

在VS中,你可以通过在那里放置一个断点来调试它并将鼠标放在DataSource上,但我认为这是因为GridView从它绑定的DataTable中提取了一个DataView,所以它没有查看DataSet ...

调试会发现。

HTH。

© www.soinside.com 2019 - 2024. All rights reserved.