ListView con DataPager non funzionante
Domanda
Da tutto quello che ho letto, sembrava che l'aggiunta del paging a un controllo ListView fosse semplice, ma non funziona per me. Dopo aver aggiunto i controlli ListView e DataPager al modulo e averli collegati insieme, sto ottenendo un comportamento molto strano. DataPager limita correttamente le dimensioni della pagina di ListView, ma facendo clic sui pulsanti di paging non influisce affatto su ListView. I pulsanti di paging sembrano pensare che stiano facendo il loro lavoro, poiché l'ultimo pulsante è disabilitato quando si passa all'ultima pagina, ecc., Ma ListView non cambia mai. Inoltre, bastano due clic su DataPager per farlo fare qualsiasi cosa, ovvero fare clic su Ultima volta non fa nulla, ma fare clic una seconda volta fa reagire DataPager come se fosse stata selezionata l'ultima pagina.
L'unica cosa a cui riesco a pensare è che sto vincolando DataSource in fase di esecuzione (a un oggetto LINQ), non usando un controllo LinqDataSource o altro. Qualcuno ha visto questo comportamento? Sto facendo qualcosa di sbagliato? Ecco il codice che sto usando:
<asp:DataPager ID="HistoryDataPager" runat="server" PagedControlID="HistoryListView" PageSize="10">
<Fields>
<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="true" ShowLastPageButton="true" />
</Fields>
</asp:DataPager>
<asp:ListView ID="HistoryListView" runat="server">
...
</asp:ListView>
Nel code-behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
HistoryListView.DataSource = From x in myContext.myTables ...
DataBind()
End If
End Sub
Soluzione
Dai un'occhiata a ListViewPagedDataSource.
private ListViewPagedDataSource GetProductsAsPagedDataSource(DataView dv)
{
// Limit the results through a PagedDataSource
ListViewPagedDataSource pagedData = new ListViewPagedDataSource();
pagedData.DataSource = dv;
pagedData.MaximumRows = dv.Table.Rows.Count;
pagedData.TotalRowCount = dpTop.PageSize;
if (Request.QueryString[dpTop.QueryStringField] != null)
pagedData.StartRowIndex = (Convert.ToInt32(Request.QueryString[dpTop.QueryStringField]) - 1) * dpTop.PageSize;
else
pagedData.StartRowIndex = 0;
return pagedData;
}
Tuttavia, ho un problema con la visualizzazione dell'ultima pagina. DataPager torna alla prima pagina, ma i dati visualizzati sono l'ultima pagina.
Altri suggerimenti
Dobbiamo rileggere la visualizzazione dell'elenco di database nell'evento OnPreRender.
protected override void OnPreRender(EventArgs e)
{
ListView1.DataBind();
base.OnPreRender(e);
}
- Aggiornamento
Dopo aver lavorato su alcune visualizzazioni elenco con asp.net ajax, ho visto una soluzione che ha più senso di quella precedente. Normalmente si rilegano i dati Listview sul metodo di caricamento della pagina o un gestore di eventi clic sul pulsante e, in caso di postback, l'associazione dei dati andrebbe persa come descritto sopra nel problema. Pertanto, è necessario associare nuovamente i dati alle proprietà della pagina modificate il gestore eventi per la visualizzazione elenco.
ListView_PagePropertiesChanged(object sender, EventArgs e)
{
ListView.DataSource=someDatasource;
ListView.DataBind()
}
Un'altra soluzione , semplice, basta ottenere " ID " in " QUERY-STRING " dal database, ora impostalo sulla proprietà Controllo cercapersone come [QueryStringField = " ID " ] come:
<asp:DataPager ID="DataPagerProducts" runat="server" QueryStringField="ID" PageSize="3">
<Fields>
<asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ShowLastPageButton="True" ShowPreviousPageButton="False" />
</Fields>
</asp:DataPager>
Nota: se non si sveglia, quindi impostare anche [PagedControlID = " ListView_Name " ]
.
Associa la visualizzazione elenco all'evento pre-rendering del datapager non al caricamento della pagina. Consulta la soluzione qui
Inoltre, se l'origine dati di ListView viene modificata (ad es. se si visualizzano dati basati su parametri di ricerca), non dimenticare di reimpostare il cercapersone ogni volta che l'origine dati viene aggiornata. Con ListView questo non è così semplice come alcuni altri controlli associati ai dati (ad esempio GridView):
private void ResetListViewPager()
{
DataPager pager = (DataPager)ListViewMembers.FindControl("DataPager1");
if (pager != null)
{
CommandEventArgs commandEventArgs = new CommandEventArgs(DataControlCommands.FirstPageCommandArgument, "");
// MAKE SURE THE INDEX IN THE NEXT LINE CORRESPONDS TO THE CORRECT FIELD IN YOUR PAGER
NextPreviousPagerField nextPreviousPagerField = pager.Fields[0] as NextPreviousPagerField;
if (nextPreviousPagerField != null)
{
nextPreviousPagerField.HandleEvent(commandEventArgs);
}
// THIS COMMENTED-OUT SECTION IS HOW IT WOULD BE DONE IF USING A NUMERIC PAGER RATHER THAN A NEXT/PREVIOUS PAGER
//commandEventArgs = new CommandEventArgs("0", "");
//NumericPagerField numericPagerField = pager.Fields[0] as NumericPagerField;
//if (numericPagerField != null)
//{
// numericPagerField.HandleEvent(commandEventArgs);
//}
}
}
<asp:ListView ID="ListView1" runat="server" DataSourceID="sdsImages">
<ItemTemplate>
<div class="photo sample12">
<asp:Image ID="img_Galerie" runat="server" ImageUrl='<%# "~/imageHandler.ashx?ID=" + Eval("ImageID") %>' />
</div>
</ItemTemplate>
</asp:ListView>
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="3" QueryStringField="ImageID">
<Fields>
<asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ShowLastPageButton="True" ShowPreviousPageButton="False" />
</Fields>
</asp:DataPager>
<asp:SqlDataSource ID="sdsImages" runat="server"
ConnectionString="<%$ ConnectionStrings:DBCS %>"
SelectCommand="SELECT ImageID FROM Images ">
prova questo:
protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
ListView1.DataSource = productList;
ListView1.DataBind();
DataPager1.DataBind();
}