2009-06-15 9 views
6

C'è una strada più breve per fare un FooterTemplate (in un GridView) sempre visibile, anche quando DataSource è vuota?Mostra sempre FooterTemplate, anche non ci sono dati

+0

Perché vuoi ottenere questo? –

+0

Si prega di dare un'occhiata a ciò che ho commentato di seguito, ho spiegato quello che mi serve per. – Shimmy

risposta

5

Se si desidera che venga sempre visualizzato, indipendentemente dal contenuto, non è sufficiente inserire il footer html all'esterno dello GridView anziché nello FooterTemplate?

Se questo non è un'opzione per qualche motivo, allora potete o add an null row to your data source if it's empty o subclass the GridView & override the default behaviour.

Quelle sono le uniche opzioni io sappia (anche se il suo stato un po 'che l'ultima volta che ho usato un GridView).

+0

Non mi interessa davvero farlo con Html, il problema è che voglio che le colonne si adattino alla larghezza delle colonne GridView. Voglio che mostri qualche riepilogo quando esistono i dati e un elemento di inserimento (che ho implementato nel footer, so cosa intendo?) Quando il pulsante "Nuovo" viene premuto sul modello dell'articolo, o mostra sempre il piè di pagina. in altre parole: * c'è un modo per evocare mostrando il piè di pagina (quando non ci sono dati)? * ciò che è in realtà questa cosa riga di dati null, non ha ottenuto (im utilizzando EntityDataSource, penso che sarà più complicato o impossibile a tutti). Grazie amico. – Shimmy

+0

Non voglio usare una riga vuota, non mi interessa la sottoclasse di GridView ma nessun dato fittizio. hai qualcosa? – Shimmy

+1

Il 2 ° link che ho incluso (http://mattberseth.com/blog/2007/07/how%5Fto%5Fshow%5Fheader%5Fand%5Ffooter.html) ha qualche codice di esempio per consentire di avere una griglia con una proprietà ShowFooterWhenEmpty . – Alconja

7

stavo avendo problemi con questo. Il link da Alconja aiuta molto (Grazie Alconja) ma GridView.FooterRow restituisce quindi null. Ne ho bisogno per inserire nuovi record dal piè di pagina.

Questa è la mia soluzione finale che funziona. Ora puoi inserire dati dal piè di pagina anche se la griglia è vuota.

GridViewExtended.cs (una classe nella cartella 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; 
    } 
    } 

} 

Nella aspx pagina , è sufficiente aggiungere

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

e sostituirlo con <asp:GridView<YourPrefix:GridViewExtended

Spero che aiuti qualcuno.

+0

Ho provato questo perché avevo una gridview con un piè di pagina con l'opzione di aggiungere un nuovo record. Gli utenti dovevano fare clic su un pulsante "Aggiungi nuovo" nel piè di pagina dopo il quale avrebbero visualizzato i controlli per aggiungere una nuova riga. Questo codice non funziona come previsto (probabilmente dovresti sostituire la chiamata a base.CreateChildControls con il codice e impostare l'id, ecc.). –

+1

Il problema per me con questa soluzione è che l'evento RowDataBound non viene attivato per il footer per qualche motivo quando la griglia è vuota. Poiché ho bisogno di compilare alcuni dropdown, questo è un difetto fatale. –

+0

Questo è fantastico! Grazie! – jazzBox

2

Come uno dei commentatori precedenti citati, l'evento RowDataBound non si attiva per il piè di pagina. Ho trovato un altro frammento di codice che è addresses this issue, ma oltre a visualizzare il piè di pagina, crea esplicitamente la riga (attivando l'evento RowCreated) e lo associa (attivando l'evento RowDataBound).

ho convertito il codice di cui sopra si fa riferimento a C# utilizzando un convertitore di codice e ha fatto un paio di modifiche minori. Ho incluso anche i commenti che ho fatto mentre ho passato il codice per scomporlo. Gli eventi RowCreated e RowDataBound sono attivi ora e sono in grado di compilare i menu a discesa nei piè di pagina.

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

     } 

    }