Всегда показывать FooterTemplate, даже без данных - PullRequest
6 голосов
/ 15 июня 2009

Есть ли короткий способ сделать FooterTemplate (в GridView) всегда видимым, даже когда DataSource пуст?

Ответы [ 3 ]

7 голосов
/ 05 июня 2012

У меня тоже были проблемы с этим. Ссылка от 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

Надеюсь, это кому-нибудь поможет.

5 голосов
/ 15 июня 2009

Если вы хотите, чтобы он отображался всегда, независимо от содержимого, вы не можете просто поместить html нижнего колонтитула за пределы GridView вместо FooterTemplate?

Если по какой-то причине это невозможно, вы можете либо добавить пустую строку в ваш источник данных, если он пуст , либо подкласс GridView и изменить поведение по умолчанию .

Это единственные варианты, которые мне известны (хотя с тех пор, как я в последний раз использовал GridView), прошло некоторое время.

3 голосов
/ 04 июня 2014

Как упомянул один из предыдущих комментаторов, событие 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;
            }

        }

    }
...