次の例を見てください...ListView
のデータのページングに使用されるDataPager
とListView
のページ:
コードビハインド:
protected void Page_Load(object sender, EventArgs e)
{
MyList.DataSource = GetSomeList();
MyList.DataBind();
}
出典:
<asp:ListView ID="MyList" runat="server">
<% //LayoutTemplate and ItemTemplate removed for the example %>
</asp:ListView>
<asp:DataPager ID="ListPager" PagedControlID="MyList" runat="server" PageSize="10">
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
DataPager
の問題は、それが常にバインディングの一歩遅れであるということです。
たとえば、ページが読み込まれると、ページ番号1になります。次に、ページ3をクリックすると、ポストバック後もページ1に留まります。次に、5ページをクリックすると、ポストバックの後、3ページに表示されます...その後、6ページをクリックすると、5ページに表示されます...というように続きます。
ページングが期待どおりに機能しないのはなぜですか?
この問題は、Page_Load
イベントで発生するバインディングが原因です。
これが期待どおりに機能するためには、バインディングはPage_Load
ではなくDataPager
のOnPreRender
イベントで発生する必要があります。
出典:
<asp:DataPager ID="ListPager" PagedControlID="MyList" runat="server" PageSize="10"
OnPreRender="ListPager_PreRender">
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
コードビハインド:
protected void Page_Load(object sender, EventArgs e)
{
//Binding code moved from Page_Load
//to the ListView's PreRender event
}
protected void ListPager_PreRender(object sender, EventArgs e)
{
MyList.DataSource = GetSomeList();
MyList.DataBind();
}
私はこれと同じ問題に遭遇しましたが、データページの事前レンダリングで毎回バインドすることは私にとってオプションではありませんでした。代わりに、ページングが発生したときにのみバインドすることで、ほぼ同じことを実行できました。このソリューションは、Andreasによる事前レンダリングソリューションの代替として使用できます。以下は私のために働いた:
ListViewのPagePropertiesChangedイベントにアタッチすることで、データページャーのすべてのプリレンダーにバインドすることなく、ページングの問題を修正することができました。
注:ほとんどのデータページャーのプロパティはスキンファイルで設定されているため、マークアップには含まれていません。
マークアップ:
<asp:DataPager ID="ListPager" runat="server" PagedControlID="MyList" />
<asp:ListView ID="MyList" runat="server">
<% //LayoutTemplate and ItemTemplate removed for the example %>
</asp:ListView>
コードビハインド:
protected void Page_Load(object sender, EventArgs e) {
MyList.PagePropertiesChanged += new EventHandler(MyList_PagePropertiesChanged);
}
/// <summary>
/// Handles the situation where the page properties have changed. Rebind the data
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MyList_PagePropertiesChanged(object sender, EventArgs e) {
MyList.DataSource = GetSomeList();
MyList.DataBind();
}
データページャーにOnPreRenderイベントがありません!
以下は私にぴったりです。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ds As DataSet
ds = SQLHELPER.ExecuteDataSet(CommandType.StoredProcedure, "sp_Locations")
rs.EnableViewState = False
rs.DataSource = ds
rs.DataBind()
End Sub
Protected Sub rs_PagePropertiesChanging(ByVal sender As Object, ByVal e As PagePropertiesChangingEventArgs)
'set current page startindex, max rows and rebind to false
Pager.SetPageProperties(e.StartRowIndex, e.MaximumRows, False)
'rebind List View
rs.DataBind()
End Sub
<asp:ListView ID="rs" runat="server" onpagepropertieschanging="rs_PagePropertiesChanging">
または、ListViewのみを含むユーザーコントロールを構築している場合、Page_Loadメソッドは他に何も実行していないため、ページャーイベントハンドラーをPage_Load
メソッドにポイントするだけです。
<asp:DataPager ID="ListPager" PagedControlID="MyList" runat="server" PageSize="10"
OnPreRender="Page_Load">