始终显示 FooterTemplate,即使没有数据

发布于 2024-07-24 06:32:15 字数 71 浏览 8 评论 0 原文

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

Is there a short way to make a FooterTemplate (in a GridView) always visible, even when DataSource is empty?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天冷不及心凉 2024-07-31 06:32:15

我也遇到了这个问题。 来自 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" %>

并将其替换为

希望它对某人有帮助。

I was having trouble with this as well. The link from Alconja helps a lot (Thanks Alconja) but GridView.FooterRow then returns null. I need it for inserting new records from the footer.

This is my final solution that works. Now you can insert data from the footer even if the grid is empty.

GridViewExtended.cs (a class in the App_Code folder):

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

}

In the aspx page, simply add

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

and replace <asp:GridView with <YourPrefix:GridViewExtended

Hope it helps someone.

同尘 2024-07-31 06:32:15

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

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

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

If you want it to always display, regardless of content, can't you just put the footer html outside the GridView, instead of in the FooterTemplate?

If that's not an option for some reason, then you can either add an null row to your data source if it's empty, or subclass the GridView & override the default behaviour.

Those are the only options I'm aware of (although its been a while since the last time I used a GridView).

南城旧梦 2024-07-31 06:32:15

正如前面的评论者之一提到的,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;
            }

        }

    }

As one of the previous commenters mentioned, the RowDataBound event doesn't fire for the footer. I found another code snippet that addresses this issue, but in addition to displaying the footer, it explicitly creates the row (firing the RowCreated event) and binds it (firing the RowDataBound event).

I've converted the above referenced code to c# using a code converter and made a few minor tweaks. I also included the comments I made as I stepped through the code to break it down. The RowCreated and RowDataBound events are firing now and I'm able to populate dropdowns in footers.

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

        }

    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文