2009-06-15 4 views
6

Existe-t-il un moyen rapide de rendre un FooterTemplate (dans un GridView) toujours visible, même lorsque DataSource est vide?Toujours afficher FooterTemplate, même sans données

+0

Pourquoi voulez-vous cela? –

+0

S'il vous plaît jeter un oeil à ce que j'ai commenté ci-dessous, j'ai expliqué ce que j'ai besoin pour. – Shimmy

Répondre

5

Si vous voulez qu'il s'affiche toujours, quel que soit le contenu, ne pouvez-vous pas simplement mettre le pied de page html en dehors du GridView, au lieu de dans le FooterTemplate?

Si ce n'est pas une option pour une raison quelconque, alors vous pouvez soit add an null row to your data source if it's empty, ou subclass the GridView & override the default behaviour.

Ce sont les seules options dont je suis conscient (bien que cela ait été un moment depuis la dernière fois que j'ai utilisé un GridView).

+0

Je ne me soucie pas vraiment de le faire avec Html, le problème est que je veux que les colonnes correspondent à la largeur des colonnes GridView. Je veux qu'il montre un résumé quand les données existent, et un élément d'insertion (que j'ai implémenté dans le pied de page, sais-je ce que je veux dire?) Quand le bouton "Nouveau" est appuyé sur le modèle d'élément ou affiche toujours le pied. en d'autres termes: * existe-t-il un moyen d'évoquer l'affichage du pied de page (en l'absence de données)? * ce qui est réellement cette chose de ligne de données nul, n'a pas getcha (Im utilisant EntityDataSource, je pense sera plus compliqué ou impossible du tout). Merci mon pote. – Shimmy

+0

Je ne veux pas utiliser une ligne vide, cela ne me dérange pas de sous-classer le GridView mais pas de données factices. Tu as quelque chose? – Shimmy

+1

Le 2ème lien que j'ai inclus (http://mattberseth.com/blog/2007/07/how%5Fto%5Fshow%5Fheader%5Fand%5Ffooter.html) a un exemple de code pour vous permettre d'avoir une grille avec une propriété ShowFooterWhenEmpty . – Alconja

7

J'avais aussi des problèmes avec ça. Le lien d'Alconja aide beaucoup (Merci Alconja) mais GridView.FooterRow retourne alors null. J'en ai besoin pour insérer de nouveaux enregistrements du pied de page.

Ceci est ma solution finale qui fonctionne. Vous pouvez maintenant insérer des données du pied de page même si la grille est vide.

GridViewExtended.cs (une classe dans le dossier 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; 
    } 
    } 

} 

Dans la page ASPX, ajoutez simplement

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

et REPLACE <asp:GridView avec <YourPrefix:GridViewExtended

J'espère que ça aide quelqu'un.

+0

J'ai essayé parce que j'avais un gridview avec un pied de page avec l'option d'ajouter un nouvel enregistrement. Les utilisateurs doivent cliquer sur un bouton "Ajouter un nouveau" dans le pied de page, après quoi ils verront des contrôles pour ajouter une nouvelle ligne. Ce code ne fonctionne pas comme prévu (vous devrez probablement remplacer l'appel à base.CreateChildControls avec du code et définir l'ID, etc). –

+1

Le problème pour moi avec cette solution est que l'événement RowDataBound ne se déclenche pas pour le pied de page pour une raison quelconque lorsque la grille est vide. Depuis que j'ai besoin de remplir quelques listes déroulantes là, c'est une faille fatale. –

+0

C'est génial! Merci! – jazzBox

2

Comme l'un des commentateurs précédents l'a mentionné, l'événement RowDataBound ne se déclenche pas pour le pied de page. J'ai trouvé un autre extrait de code addresses this issue, mais en plus d'afficher le pied de page, il crée explicitement la ligne (déclencher l'événement RowCreated) et le lie (déclencher l'événement RowDataBound).

J'ai converti le code référencé ci-dessus en C# en utilisant un convertisseur de code et fait quelques réglages mineurs. J'ai également inclus les commentaires que j'ai faits pendant que je passais en revue le code pour le décomposer. Les événements RowCreated et RowDataBound se déclenchent maintenant et je suis en mesure de remplir des listes déroulantes dans les pieds de page.

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

     } 

    } 
Questions connexes