Всегда показывать FooterTemplate, даже без данных

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


person Shimmy Weitzhandler    schedule 15.06.2009    source источник
comment
Почему вы хотите этого добиться?   -  person Muhammad Akhtar    schedule 15.06.2009
comment
Пожалуйста, взгляните на то, что я прокомментировал ниже, я объяснил, для чего мне это нужно.   -  person Shimmy Weitzhandler    schedule 15.06.2009


Ответы (3)


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

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

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

person Alconja    schedule 15.06.2009
comment
Мне все равно, что делать это с помощью Html, проблема в том, что я хочу, чтобы столбцы соответствовали ширине столбцов GridView. Я хочу, чтобы он показывал некоторое обобщение, когда данные существуют, и элемент вставки (который я реализовал в нижнем колонтитуле, знаете, что я имею в виду?), Когда кнопка New нажата в шаблоне элемента, или всегда показывать нижний колонтитул. другими словами: * есть ли способ вызвать показ нижнего колонтитула (при отсутствии данных)? * что на самом деле представляет собой эта пустая строка данных, не понял (я использую EntityDataSource, я думаю, будет сложнее или вообще невозможно). Спасибо дружище. - person Shimmy Weitzhandler; 15.06.2009
comment
Я не хочу использовать пустую строку, я не против создания подкласса GridView, но без фиктивных данных. у тебя есть кое-что? - person Shimmy Weitzhandler; 16.06.2009
comment
Вторая ссылка, которую я включил (mattberseth.com/ blog / 2007/07 /) есть пример кода, позволяющий получить сетку со свойством ShowFooterWhenEmpty. - person Alconja; 16.06.2009

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

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

person Aximili    schedule 05.06.2012
comment
Я пробовал это, потому что у меня было сетка с нижним колонтитулом с возможностью добавления новой записи. Пользователи должны будут нажать кнопку «Добавить новый» в нижнем колонтитуле, после чего они увидят элементы управления для добавления новой строки. Этот код не работает должным образом (вам, вероятно, придется заменить вызов base.CreateChildControls кодом и установить идентификаторы и т. Д.). - person Tahir Hassan; 03.09.2012
comment
Для меня проблема с этим решением заключается в том, что событие RowDataBound по какой-то причине не запускается для нижнего колонтитула, когда сетка пуста. Поскольку мне нужно заполнить несколько раскрывающихся списков, это фатальный недостаток. - person see sharper; 16.05.2014
comment
Отлично! Спасибо! - person jazzBox; 25.01.2016
comment
ShowFooterWhenEmpty = True - person Mina Gabriel; 22.01.2017

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

        }

    }
person Taco Human    schedule 04.06.2014