8

是否有一种简短的方法可以使 FooterTemplate(在 GridView 中)始终可见,即使 DataSource 为空?

4

3 回答 3

7

我也遇到了麻烦。来自 Alconja 的链接有很大帮助(感谢 Alconja),但 GridView.FooterRow 然后返回 null。我需要它来从页脚插入新记录。

这是我的最终解决方案。现在,即使网格为空,您也可以从页脚插入数据。

GridViewExtended.cs(App_Code 文件夹中的一个类):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace YourNamespace
{

  public class GridViewExtended : GridView
  {
    #region Public Properties
    [Category("Behavior")]
    [Themeable(true)]
    [Bindable(BindableSupport.No)]
    public bool ShowFooterWhenEmpty
    {
      get
      {
        if (this.ViewState["ShowFooterWhenEmpty"] == null)
        {
          this.ViewState["ShowFooterWhenEmpty"] = false;
        }

        return (bool)this.ViewState["ShowFooterWhenEmpty"];
      }
      set
      {
        this.ViewState["ShowFooterWhenEmpty"] = value;
      }
    }
    #endregion

    private GridViewRow _footerRow2;
    public override GridViewRow FooterRow
    {
      get
      {
        GridViewRow f = base.FooterRow;
        if (f != null)
          return f;
        else
          return _footerRow2;
      }
    }

    protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
    {
      int rows = base.CreateChildControls(dataSource, dataBinding);

      //  no data rows created, create empty table if enabled
      if (rows == 0 && (this.ShowFooterWhenEmpty))
      {
        //  create the table
        Table table = this.CreateChildTable();

        DataControlField[] fields;
        if (this.AutoGenerateColumns)
        {
          PagedDataSource source = new PagedDataSource();
          source.DataSource = dataSource;

          System.Collections.ICollection autoGeneratedColumns = this.CreateColumns(source, true);
          fields = new DataControlField[autoGeneratedColumns.Count];
          autoGeneratedColumns.CopyTo(fields, 0);
        }
        else
        {
          fields = new DataControlField[this.Columns.Count];
          this.Columns.CopyTo(fields, 0);
        }

        if (this.ShowHeaderWhenEmpty)
        {
          //  create a new header row
          GridViewRow headerRow = base.CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
          this.InitializeRow(headerRow, fields);

          //  add the header row to the table
          table.Rows.Add(headerRow);
        }

        //  create the empty row
        GridViewRow emptyRow = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
        TableCell cell = new TableCell();
        cell.ColumnSpan = fields.Length;
        cell.Width = Unit.Percentage(100);

        //  respect the precedence order if both EmptyDataTemplate
        //  and EmptyDataText are both supplied ...
        if (this.EmptyDataTemplate != null)
        {
          this.EmptyDataTemplate.InstantiateIn(cell);
        }
        else if (!string.IsNullOrEmpty(this.EmptyDataText))
        {
          cell.Controls.Add(new LiteralControl(EmptyDataText));
        }

        emptyRow.Cells.Add(cell);
        table.Rows.Add(emptyRow);

        if (this.ShowFooterWhenEmpty)
        {
          //  create footer row
          _footerRow2 = base.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
          this.InitializeRow(_footerRow2, fields);

          //  add the footer to the table
          table.Rows.Add(_footerRow2);
        }

        this.Controls.Clear();
        this.Controls.Add(table);
      }

      return rows;
    }
  }

}

aspx页面中,只需添加

<%@ Register TagPrefix="YourPrefix" Namespace="YourNamespace" %>

并替换<asp:GridView<YourPrefix:GridViewExtended

希望它可以帮助某人。

于 2012-06-05T04:50:53.753 回答
5

如果您希望它始终显示,无论内容如何,​​您不能将页脚 html 放在 之外GridView,而不是FooterTemplate?

如果由于某种原因这不是一个选项,那么您可以向数据源添加一个空行(如果它是空的),或者子类化GridView& 覆盖默认行为

这些是我知道的唯一选项(尽管距离我上次使用 a 已经有一段时间了GridView)。

于 2009-06-15T07:48:27.097 回答
3

正如前面的一位评论者所提到的,RowDataBound 事件不会为页脚触发。我找到了另一个解决此问题的代码片段,但除了显示页脚之外,它还显式创建行(触发 RowCreated 事件)并绑定它(触发 RowDataBound 事件)。

我已经使用代码转换器将上面引用的代码转换为 c# 并进行了一些小的调整。我还包括了我在逐步分解代码时所做的评论。现在正在触发 RowCreated 和 RowDataBound 事件,我可以在页脚中填充下拉菜单。

    using System.Linq;
    using System.Web.UI.WebControls;
    using System.ComponentModel;

    namespace WebUI.Controls
    {
        //modified from https://stackoverflow.com/questions/3437581/show-gridview-footer-on-empty-grid
        public class GridViewExtended : GridView
        {

            private GridViewRow _footerRow;
            [DefaultValue(false), Category("Appearance"), Description("Include the footer when the table is empty")]
            public bool ShowFooterWhenEmpty { get; set; }

            [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
            public override GridViewRow FooterRow {
                get {
                    if ((this._footerRow == null)) {
                        this.EnsureChildControls();
                    }
                    return this._footerRow;
                }
            }

            protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
            {
                //creates all the rows that would normally be created when instantiating the grid
                int returnVal = base.CreateChildControls(dataSource, dataBinding);
                //if no rows were created (i.e. returnVal == 0), and we need to show the footer row, then we need to create and bind the footer row.
                if (returnVal == 0 && this.ShowFooterWhenEmpty) {
                    Table table = this.Controls.OfType<Table>().First<Table>();
                    DataControlField[] dcf = new DataControlField[this.Columns.Count];
                    this.Columns.CopyTo(dcf, 0);
                    //creates the footer row
                    this._footerRow = this.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal, dataBinding, null, dcf, table.Rows, null);
                    if (!this.ShowFooter) {
                        _footerRow.Visible = false;
                    }
                }
                return returnVal;
            }

            private GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState, bool dataBind, object dataItem, DataControlField[] fields, TableRowCollection rows, PagedDataSource pagedDataSource)
            {
                GridViewRow row = this.CreateRow(rowIndex, dataSourceIndex, rowType, rowState);
                GridViewRowEventArgs e = new GridViewRowEventArgs(row);
                if ((rowType != DataControlRowType.Pager)) {
                    this.InitializeRow(row, fields);
                } else {
                    this.InitializePager(row, fields.Length, pagedDataSource);
                }
                //if the row has data, sets the data item
                if (dataBind) {
                    row.DataItem = dataItem;
                }
                //Raises the RowCreated event
                this.OnRowCreated(e);
                //adds the row to the gridview's row collection
                rows.Add(row);
                //explicitly binds the data item to the row, including the footer row and raises the RowDataBound event.
                if (dataBind) {
                    row.DataBind();
                    this.OnRowDataBound(e);
                    row.DataItem = null;
                }
                return row;
            }

        }

    }
于 2014-06-04T13:44:11.970 回答