2009-11-18 7 views
7

Ho un GridView che ha un DataSourceID che punta a un ObjectDataSource. ObjectDataSource punta a un metodo che restituisce un LINQ IQueryable utilizzando le proprietà TypeName, SelectMethod e SelectCountMethod del controllo ObjectDataSource. Quello che succede è che i dati vengono caricati correttamente in anticipo. Tuttavia, nel postback, se rimuovo le righe da GridView e provo a rebind usando il GridView.DataBind() esplicito, non funziona. So che LINQ sta restituendo il conteggio delle righe corretto e tale perché ho chiamato il metodo count e restituisce il conteggio delle righe corretto. Ecco un rapido esempio:GridView non riconfigura correttamente dopo il postback

<asp:GridView ID="TestGridView" runat="server" PageSize="20" 
    AutoGenerateColumns="false" AllowPaging="true" 
    AllowSorting="false" DataSourceID="TestDataSource"> 
    <Columns> 
     ... 
    </Columns> 
</asp:GridView> 

<asp:ObjectDataSource ID="TestDataSource" runat="server" 
    EnablePaging="true" SelectCountMethod="GetDetailCount" 
    SelectMethod="GetDetails" TypeName="MyApp.PageClass" /> 

Ho provato ad aggiungere un pulsante e aggiungendo il TestGridView.DataBind(); metodo per quello Ho provato ad aggiungerlo all'evento Page_PreRender. Non importa quello che provo, non funziona.

Come suggerito da qualcuno di seguito, ho provato a spostarlo anche su Page_Load e non andare. Ecco un esempio di massima del mio codice:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
     // Set "initial" query parameters, then ... 
     BindData(); 
    } 
} 

private void BindData() 
{ 
    // EDITED: Removed the code below since I'm not looking to delete the 
    //   rows from the database, but rather get the GridView to rebind 
    //   which its not. 
    ////Remove all current rows from the GridView 
    //int colCount = TestGridView.Rows.Count; 
    //for (int x = 1; x <= colCount; x++) 
    //{ 
    // TestGridView.DeleteRow(x); 
    //} 

    // Bind GridView to the ObjectDataSource 
    TestGridView.DataBind(); 
} 

protected void RegenerateImageButton_Click(object sender, ImageClickEventArgs e) 
{ 
    // Set "updated" query parameters, then ... 
    BindData(); 
} 
+0

Modificato nuovamente sopra. –

risposta

0

Dopo aver guardato al codice dietro un po 'di più, mi sono imbattuto in valori di proprietà della pagina memorizzati in ViewState. Una volta passato a Session, funzionano.

+6

Se lo spieghi in dettaglio, sarò tentato di fare +1 sulla tua soluzione. ;) –

3

un'idea stupida, ma hai controllato l'evento di caricamento della pagina con il if(!Page.IsPostBack)?

Da ASP.NET Page Framework Overview:

Page Load: Nel corso di questo evento, è possibile eseguire una serie di azioni per creare sia la vostra pagina ASP.NET per la prima volta o di rispondere a eventi lato client che derivano da un post. La pagina e lo stato della vista di controllo sono stati ripristinati prima di questo evento. Utilizzare la proprietà della pagina IsPostBack per verificare se questa è la prima volta che viene elaborata la pagina. Se è la prima volta, esegui il binding dei dati. Inoltre, leggi e aggiorna le proprietà di controllo.

Dove come

Page_PreRender: L'evento PreRender è sparato poco prima lo stato di visualizzazione viene salvato ei controlli sono resi. Puoi utilizzare questo evento per eseguire qualsiasi operazione dell'ultimo minuto sui tuoi controlli.

In effetti

Poiché la struttura delle pagine è un un stateless e modello disconnesso, ogni volta che un client richiede una pagina aspx, molte cose si verificano durante l'elaborazione della pagina ...

Quindi, in effetti, è possibile effettuare il controllo prima che venga impostato lo stato di visualizzazione anziché dopo che il viewstate è stato ripristinato. Il luogo più comune da verificare per if(!Page.IsPostBack) si trova in genere nell'evento Page_Load.

+0

Sì. Guarda qui sotto il codice di esempio: "Ho provato ad aggiungere un pulsante e ad aggiungere il metodo TestGridView.DataBind(); ho provato ad aggiungerlo all'evento Page_PreRender. Non importa quello che provo, non funziona." –

+0

Sì, anche nell'evento Page_Load non funziona. –

+0

Codice aggiornato per mostrarti cosa sto facendo. –

2

Il vostro esempio mostra

TestGridView.Columns.RemoveAt(0); 

ma avete davvero significare

TestGridView.Rows.RemoveAt(0); 

(ed è questo il problema?)

+0

Wow. Grazie Jeff. Questo aiuta, ma non risolve il mio problema. –

2

Ho avuto un problema simile con rilegatura in modo dinamico un TreeView a un XmlDataSource che ha cambiato il sorgente xml su ogni postback.Impostazione EnableCache su falso risolto. Hai provato questo? (Si consideri l'oggetto Linq2Sql memorizza nella cache già, se l'IQueryable sta usando un oggetto Linq2Sql, cioè)

<asp:ObjectDataSource ID="TestDataSource" runat="server" EnableCaching="false" 
    EnablePaging="true" SelectCountMethod="GetDetailCount" 
    SelectMethod="GetDetails" TypeName="MyApp.PageClass" /> 

se questo non funziona, provate questo accoppiato con quanto sopra:

protected override void OnPreRender(EventArgs e) 
{ 
    base.OnPreRender(e); 
    BindData(); 
} 
+0

No. Continua a non funzionare. Grazie comunque! –

+0

Grazie, ma penso di averlo capito. Problema totalmente non correlato. –

13

Le visualizzazioni di griglia non vengono reindirizzate sul postback, le loro righe vengono ritirate dal viewstate. Reimpostando il datasourceID di gridview all'ID di origine dei dati dell'oggetto al caricamento della pagina (o init?) Causerà il rimbalzo del gridview.

+0

Sì, ottima risposta! – Petras

+0

ha funzionato per me .... grazie –

+1

Ottima spiegazione, ma se il problema è il ViewState, il modo corretto per risolverlo è aggiungere EnableViewState = "false" al GridView. – Trajan

0

Ho avuto una situazione simile in cui i valori aggiornati di una riga non sono stati visualizzati, indipendentemente dal modo in cui ho tentato di eseguire il databind dopo l'aggiornamento.

Il GridView era inevitabile un ObjectDataSource, e si è verificato il problema dopo aver passato il suo oggetto protezione da una DataSet a un Entity Framework interrogazione

Abilitazione ViewState per la GridView ha il trucco per me, così:

<asp:GridView ID="GridViewTransporters" PageSize="100" 
runat="server" AllowPaging="True" AllowSorting="True" 
AutoGenerateColumns="False" DataSourceID="ObjectDataSourceTransporters" 
DataKeyNames="Id" EnableViewState="True">