2009-07-16 7 views
5

sto creando un GridView in un metodo in questo modo:Modifica delle proprietà delle colonne GridView dal code-behind

GridView gridView = new GridView(); 
gridView.DataSource = reportData.Tables[0]; 
gridView.DataBind(); 

sto successivamente esportarlo in Excel e funziona benissimo. Le colonne vengono generate automaticamente dai miei dati di origine. Vorrei cambiare la proprietà DataFormatString di alcune colonne comunque dopo I database e prima che esporti in Excel. Non riesco a trovare la proprietà corretta da modificare. Qualcuno può indicarmi la giusta direzione?

risposta

7

Secondo AutoGenerateColumns documentation:

Questa opzione fornisce un modo conveniente per visualizzare tutti i campi nei dati di origine; tuttavia, è disponibile il limitato al controllo di un campo di colonna generato automaticamente o si comporta.

Nota: Automaticamente generati campi colonna associata non sono aggiunto alla collezione Columns.

Sono stanco di cercare questi AutoGeneratedField s senza fortuna.
mi viene in mente diverse opzioni per ottenere che (dal peggiore al migliore):

  1. aggiungere un evento alla rete (come RowDataBound), questo vi darà l'accesso alle cellule le righe, ma non è troppo conveniente.
  2. Non utilizzare AutoGeneratedField Creare queste colonne manualmente, come in:

    BoundField dateField = new BoundField(); 
    dateField.HeaderText = "Date"; 
    dateField.DataField = "date"; 
    dateField.DataFormatString = "{0:MMMM, yyyy}"; 
    gridView.Columns.Add(dateField); 
    

    Questa opzione permette di controllare voi bes su titoli.

  3. Aggiungere un altro livello per la formattazione e la presentazione dei dati. Questa è probabilmente l'opzione migliore. Inoltre, in questo modo non è necessario utilizzare DataTables, un GridView può vincolato a qualsiasi raccolta di oggetti con proprietà pubbliche (ad esempio, a List<Employee)) e AutoGeneratedField li trasforma in colonne.
    Penso che questa sia l'opzione migliore. Supponiamo di poter accedere alle colonne automatiche, e allora? Dovresti cercare una colonna in base al suo nome o indice, che sembra molto disordinato e aumenta l'accoppiamento.

E, come ultima nota, dovresti pensare a creare file Excel usando l'API. Non è così facile, ma i file XLS HTML sono meno compatibili con Excel 2007 - visualizza un messaggio di avviso che il formato del file non è compatibile con l'estensione e, peggio, il file frena se è aperto e salva (può essere Save As), rendendo i tuoi file meno user-friendly.

+0

L'utilizzo dell'API richiede che Excel sia installato sul server ... corretto? –

+0

Credo di sì se usi l'interoperabilità tra ufficio. Se crei file xlsx (di Office 2007), sono fondamentalmente un gruppo di file XML compressi, quindi puoi crearli in modo relativamente semplice (meglio - trovare una libreria). È inoltre possibile scrivere in Excel tramite una stringa di connessione e ole db. Il modo più semplice, btw (senza la formattazione), è creare un file CSV. – Kobi

+0

Non riesco a installare Excel sul server. Non posso usare i file xlsx perché devono essere compatibili con il 2000 e il 2003. La formattazione è necessaria, quindi non posso usare csv. Penso che potrei provare il tuo secondo suggerimento sopra e vedrò come funziona. Grazie! –

-1

Questo è il problema di come funziona asp.net. Quando crei alcuni controlli (colonne) in un metodo e imposti i controlli impostati all'utente, la volta successiva che l'utente invierà i dati a te, non avrai accesso a tali colonne poiché essi ... non esistono. Ogni volta che visualizzi il tuo sito, viene creato un nuovo oggetto (istanza).
L'unico modo per essere in grado di ottenere i dati in post indietro dai controlli creati in precedenza è quello di creare controlli nel metodo Page_Init ...

+0

Non sono sicuro di aver capito cosa sto cercando di fare qui. Sto creando un'istanza della griglia nel codice per esportarla immediatamente in Excel. Il postback non è un problema. –

0

Ad esempio:

String newDataFormatString = "{0:d}"; 
BoundField bf = gridView.Columns[Index] as BoundField; 
if (bf != null) { 
    bf.DataFormatString = "{0}"; // workaround to sync with ViewState (it's documented) 
    bf.DataFormatString = newDataFormatString; 
} 
+0

Appare quando si utilizza AutoGenerateColumns la raccolta Columns è vuota, sebbene il risultato finale abbia effettivamente colonne. –

-1

Ecco un estratto da un esportatore GridView ho scritto che converte i controlli in un GridView in letterali che vengono riformattati. Potrebbe essere di qualche aiuto:

 /// <summary> 
    /// Parses and cleans up data from the GridView controls collection 
    /// to make the data more suitable for Exported 
    /// </summary> 
    /// <param name="gv">The GridView to parse</param> 
    private void CleanUpControls(Control gv) 
    { 
     Literal l = new Literal(); 

     for (int i = 0; i < gv.Controls.Count; i++) 
     { 

      if (gv.Controls[i].GetType() == typeof (LinkButton)) 
      { 
       l.Text = (gv.Controls[i] as LinkButton).Text; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType() == typeof (ListControl)) 
      { 
       l.Text = (gv.Controls[i] as ListControl).SelectedItem.Text; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType() == typeof (CheckBox)) 
      { 
       l.Text = (gv.Controls[i] as CheckBox).Checked ? "True" : "False"; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType() == typeof (BooleanImage)) 
      { 
       l.Text = (gv.Controls[i] as BooleanImage).Value ? "True" : "False"; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType().ToString() == "System.Web.UI.WebControls.PagerTable") 
       ReplaceWithLiteral(gv, l, i); 

      else if (gv.Controls[i].GetType() == typeof (HyperLink)) 
      { 
       HyperLink hl = gv.Controls[i] as HyperLink; 
       if (MakeHyperLinksAbsolute) 
       { 
        if (hl != null) 
         hl.NavigateUrl = UrlHelper.MakeAbsoluteUrl(hl.NavigateUrl); 
       } 

       switch (TreatHyperLinksAs) 
       { 
        case HyperLinkMode.Text: 
         l.Text = hl.Text; 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.NavigateUrl: 
         if (hl != null) l.Text = hl.NavigateUrl; 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.ToolTip: 
         l.Text = hl.ToolTip; 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.TextAndLink: 
         l.Text = String.Format("{0} ({1})", hl.Text, hl.NavigateUrl); 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.HyperLink: 
         break; 
       } 
      } 

      if (gv.Controls[i].HasControls()) 
       CleanUpControls(gv.Controls[i]); 
     } 
    } 
+0

Questo non aiuta molto nel contesto della mia domanda. Sono sicuro che è utile per altre applicazioni. –