當我們ListView的資料來源是採用動態綁定的方式時,
在換頁上會遇到需點擊第二次才換到正確頁碼的問題… 讓我們用上篇的Code,稍為修改一下來做測試:
<asp:ListView ID="Main_LV" runat="server" ItemPlaceholderID="PH_Inner">
<LayoutTemplate>
<div style="width:300px;border:gray 1px dotted;margin:2px">
<ul>
<asp:PlaceHolder ID="PH_Inner" runat="server" />
</ul>
</div>
</LayoutTemplate>
<ItemTemplate>
<li>
<%# Eval("Name") %>
<small><%# Eval("DateTimeCreate","{0:yyyy-MM-dd}") %></small>
</li>
</ItemTemplate>
</asp:ListView>
<div style="width:300px;border:blue 1px dotted;margin:2px">
<asp:DataPager ID="Main_DP" runat="server" PageSize="3" PagedControlID="Main_LV" runat="server">
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
</div>
在僅有ListView與DataPager情況下,我們在CodeFile中這麼寫:
protected void Page_Load( object sender, EventArgs e )
{
//讓資料繫結僅在第一次執行
if( !Page.IsPostBack )
{
Main_LV.DataSource = VirtualDAL.GetMembers();
Main_LV.DataBind();
}
}
你會發現,雖然沒有出錯、可以正常執行, 但是分頁的執行動作,卻要點第二次才會換到正確頁碼 其實我們能從反射WebControl的原始碼得知,當執行換頁動作時, 會觸發DataPager的SetPageProperties事件,而此事件將經由DataPager已連結的控制項, 最終會執行IPageableItemContainer.SetPageProperties函式來達成分頁效果。 (實作IPageableItemContainer的控制項, 目前只有ListView) 簡單的說,我們只要在換頁動作時去觸發DataPager的SetPageProperties事件即可, 那我們就可以在剛剛程式碼加上:
protected void Page_Load( object sender, EventArgs e )
{
//讓資料繫結僅在第一次執行
if( !Page.IsPostBack )
{
Main_LV.DataSource = VirtualDAL.GetMembers();
Main_LV.DataBind();
}
// 為ListView的PagePropertiesChanging事件
// 加入一個匿名事件, 目的是執行DataPager的SetPageProperties函式
// 並且對執行中ListView重新繫結資料
Main_LV.PagePropertiesChanging += ( obj, arg ) =>
{
Main_DP.SetPageProperties( arg.StartRowIndex, arg.MaximumRows, false );
var senderLV = obj as ListView;
senderLV.DataSource = VirtualDAL.GetMembers();
senderLV.DataBind();
};
}
我們為ListView的PagePropertiesChanging,加入一個對應的事件,這邊Random用Lambda來寫, 帶入的參數是obj(ListView)及arg(PagePropertiesChangingEventArgs) 重點就在於SetPageProperties,並且重新做資料繫結。 這樣子在點擊換頁時就可以正確執行囉 一個偷吃步的做法
其實有的時候,你可能並不是在畫面中處理那麼多事務,單純的只是要顯示資料的話,或許有些人覺得還要替ListView額外寫PagePropertiesChanging事件還蠻麻煩的… 其實有比較簡單的做法,Random一般也用這招, 但因為似乎比較不是正確的做法,所以才叫偷吃步啦 我們知道在.Net的生命週期中,其實一般點擊的事件是在PageLoad之後才執行, 當你點擊DataPager執行分頁動作,其實會觸發自身SetPageProperties, 向ListView設定好頁碼,並且儲存到ViewState中去, 不過這樣就會變成你已經先綁定完資料,才告訴ListView它要換到哪一頁去, 簡單說,如果能在綁定資料之前就告訴ListView正確的頁碼,那就能正確執行了。 那...非常簡單,我們把在 Page_Load 事件中執行的事情,往後移就可以了, 所以我們的Page_Load部份程式碼可以改成:
//把Page_Load事件改為Page_LoadComplete
//protected void Page_Load( object sender, EventArgs e )
protected void Page_LoadComplete( object sender, EventArgs e )
{
Main_LV.DataSource = VirtualDAL.GetMembers();
Main_LV.DataBind();
}
因為我們將資料綁定在Page_LoadComplete才執行, 變成已經觸發完換頁事件,才進行資料綁定到ListView, 所以我們就可以正常的使用DataPager囉,提供給各位參考參考
2010-04-28 19:36:00 By RazgrizHsu
1184 Visits
|
文章分類 Category關於站長 About
大家來噗浪 Plurk武林高手連結 Links免責聲明 Disclaimer
|