Copyright © 2003-2009
By Suthep Sangvirotjanaphat
  Mobile: 089-967-2200, 081-915-7816
Phone: 0-2992-4877   Fax: 0-2992-4878
Fast Contact Us
^
%
.

GreatFriends.Biz Community

Custom Search
 MESSAGE #115242 (อ่าน 2,505 ครั้ง)

ASP.NET: การจัดหน้าเพื่อแสดงผลสำหรับ DataList Control และ Control ประเภท Data-bound Control โดยใช้ PagedDataSource

Tags: Web, VB, C#, .NET 2, VS 2008, Access, Article
สวัสดีครับ ครั้งนี้เป็นครั้งที่สองที่ผมเขียนบทความมาโพสต์ที่เกรทเฟรนด์สแห่งนี้ และเป็นครั้งแรกที่เป็นบทความทางด้านเทคนิคในเรื่องของ ASP.NET
 
ที่จริงเรื่องนี้ผมเขียนเป็นเชิงบันทึกไว้ให้ตัวเองดูกันลืมที่สเปซของผมเอง แต่หลังจากที่ได้พูดคุยแลกเปลี่ยนความเห็นกับคุณนุชิต(nano)แล้ว ก็เห็นด้วยกับคุณ nono ว่า น่าจะเป็นประโยชน์สำหรับโปรแกรมเมอร์มือใหม่ที่อาจจะพบปัญหาคล้ายๆกัน ก็เลยเอามาเขียนสรุปรวบยอดใหม่ จาก 2 ตอนรวบเป็นตอนเดียว แล้วเอามา re-post ไว้ที่เว็บเกรทเฟรนด์สแห่งนี้ครับ หวังว่าคงจะเป็นประโยชน์แก่เพื่อนๆพอสมควร
 
เอาล่ะครับ มาเริ่มกันเลย
 
ปกติผมไม่ค่อยจะได้ใช้งาน DataList Control บ่อยนัก อาจจะเพราะไม่ถนัด หรือใช้ GridView บ่อยกว่า ทำให้เวลานำมาใช้งานแต่ละครั้งก็เกิดความลำบากไม่น้อย เมื่อต้องการที่จะจัดหน้าให้กับมัน เนื่องด้วยเจ้า Control ตัวนี้ ไม่มี Property ที่เกี่ยวกับการจัดหน้าสำหรับแสดงผล เช่น AllowPaging, PageSize, etc. มาให้ เหมือนใน GridView ดังนั้นจึงต้องหาศัยผู้ช่วย ซึ่งเจ้าคลาส PagedDataSource นี่แหละครับคือฮีโร่สำหรับงานนี้
 
คลาส PagedDataSource นี้อยู่ในเนมสเปซ System.Web.UI.WebControls ซึ่งอยู่ในแอสเซมบลี System.Web (ใน System.Web.dll) อีกที เจ้าคลาส PagedDataSource ตัวนี้ เป็นคลาสที่รวบรวมนำเอา property ต่างๆ ที่เกี่ยวข้องกับการแสดงผลแบบที่แบ่งเป็นหน้า มาไว้ใช้สำหรับ Control ประเภท Data-bound Control ทั้งหลาย เช่น DataList, Detail View, Form View,... รวมไปถึง DataGrid และ GridView ด้วย พูดง่ายๆก็คือเจ้า PagedDataSource ตัวนี้ จะช่วยให้ Control ประเภท Data-bound Control เหล่านี้ สามารถแสดงผลในรูปแบบที่แบ่งเป็นหน้าๆ ได้นั่นเอง (สำหรับรายละเอียดต่างๆ ของ PagedDataSource นี่ สามารถไปดูเพิ่มเติมได้ที่ msdn นะครับ)
 
ตัวอย่างการทำ paging สำหรับ DataList โดยใช้ DropDownList Control เป็นตัวเลือกแต่ละหน้า

1. กำหนดตัวแปร currentPageIndex ให้เป็น property ของ Page และเก็บค่าไว้ใน ViewState เพื่อให้จำหน้าปัจจุบันได้ จะได้สามารถเลื่อนหน้าไปมาได้
C#
private int currentPageIndex { get { return (int)ViewState["currentPage"]; } set { ViewState["currentPage"] = value; } }

VB
Private Property currentPageIndex() As Integer
    Get
        Return Convert.ToInt32(ViewState("currentPage"))
    End Get
    Set(ByVal value As Integer)
        ViewState("currentPage") = value
    End Set
End Property

2. สร้าง instance object ของ PagedDataSource และกำหนด Bind ข้อมูลเข้ากับ objec PagedDataSource
C#
private void BindControl() {
    // ...
    // อ่านข้อมูลจากฐานข้อมูล มาใส่ไว้ใน DataTable dt
    // ...
    DataView dv = dt.DefaultView;

    PagedDataSource pgNdx = new PagedDataSource();

    pgNdx.DataSource = dv;          // Bind DataView ให้กับ PageDataSource object

    pgNdx.PageSize = 5;               // กำหนดจำนวนรายการที่ต้องการให้แสดงในแต่ละหน้า

    pgNdx.AllowPaging = true;      // กำหนดว่าให้มีการทำ paging ได้

    ddlPageIndex.Items.Clear();    // เพิ่มจำนวนหน้าลงใน DropDownList Control

    for (int i = 0; i <= (pgNdx.PageCount - 1); i++) {

        ddlPageIndex.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i + 1)));

    }

    ddlPageIndex.SelectedIndex = currentPageIndex;

    pgNdx.CurrentPageIndex = currentPageIndex;

    DataList1.DataSource = pgNdx;

    DataList1.DataBind();

}

VB
Private Sub BindControl()
    '-- ...
    '-- อ่านข้อมูลจากฐานข้อมูล มาใส่ไว้ใน DataTable dt
    '-- ...

    Dim dv As DataView = dt.DefaultView
    Dim pgNdx As New PagedDataSource()
    pgNdx.DataSource = dv        '-- Bind DataView ให้กับ PageDataSource object
    pgNdx.PageSize = 5             '-- กำหนดจำนวนรายการที่ต้องการให้แสดงในแต่ละหน้า
    pgNdx.AllowPaging = True    '-- กำหนดว่าให้มีการทำ paging ได้

    ddlPageIndex.Items.Clear()   '-- เพิ่มจำนวนหน้าลงใน DropDownList Control
    For i As Integer = 0 To (pgNdx.PageCount - 1)
        ddlPageIndex.Items.Add(New ListItem(Convert.ToString(i + 1), Convert.ToString(i + 1)))
    Next
    ddlPageIndex.SelectedIndex = currentPageIndex
    pgNdx.CurrentPageIndex = currentPageIndex

    DataList1.DataSource = pgNdx
    DataList1.DataBind()
End Sub

3. กำหนดการจัดการเมื่อมีการเปลี่ยนหน้าโดยการเลือกจาก DropDownList Control
C#
void ddlPageIndex_SelectedIndexChanged(object sender, EventArgs e) {

    currentPageIndex = Convert.ToInt32(ddlPageIndex.SelectedValue) - 1;

    BindControl();

}

VB
Protected Sub ddlPageIndex_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlPageIndex.SelectedIndexChanged
        currentPageIndex = CInt(ddlPageIndex.SelectedValue) - 1
        BindControl()
End Sub

 
เท่านี้ก็เรียบร้อยครับ สามารถจัดแบ่งหน้าให้กับ Control DataList โดยใช้  DropDownList Control เป็นตัวช่วยในการเลือกการแสดงผลในหน้าที่ต้องการได้แล้ว
ต่อไปจะเป็นการพัฒนาเพิ่มเติม โดยจะเพิ่มปุ่ม Back และ Next เข้าไป แล้วนำ DropDownList Control มาแทรกไว้ตรงกลาง โดยกำหนดคุณสมบัติของปุ่มที่เพิ่มเติมขึ้นมาดังนี้
 
หากเป็นหน้าแรก ปุ่ม Back จะถูก Disable หากเป็นหน้าสุดท้าย ปุ่ม Next จะถูก Disable หากข้อมูลมีการแสดงผลให้หน้าเดียว ปุ่ม Back และ Next จะถูก Disable พร้อมกัน เมื่อกดปุ่ม Back จะแสดงข้อมูลย้อนหลังไป 1 หน้า และเมื่อกดปุ่ม Next จะแสดงข้อมูลหน้าถัดไป ส่วนการเลือกดูข้อมูลที่หน้าใดๆก็จะสามารถเลือกจาก DropDownList Control เหมือนเดิม ซึ่งเราจะทำได้โดยเพิ่มการตรวจสอบหน้าแรกหรือหน้าสุดท้าย โดยใช้ property "IsFirstPage" และ "IsLastPage" ของคลาส PagedDataSource มาตรวจสอบ (บรรทัดที่โค้ดตัวหนา) ในฟังก์ชั่น BindControl ดังนี้
C#
private void BindControl() {
        // ...
        // อ่านข้อมูลจากฐานข้อมูล มาใส่ไว้ใน DataTable
        // ...
        DataView dv = dt.DefaultView;
        PagedDataSource pgNdx = new PagedDataSource();
        pgNdx.DataSource = dv;          // Bind DataView ให้กับ PageDataSource object
        pgNdx.PageSize = 5;               // กำหนดจำนวนรายการที่ต้องการให้แสดงในแต่ละหน้า
        pgNdx.AllowPaging = true;       // กำหนดว่าให้มีการทำ paging ได้
        ddlPageIndex.Items.Clear();     // เพิ่มจำนวนหน้าลงใน DropDownList Control
        for (int i = 0; i <= (pgNdx.PageCount - 1); i++) {
            ddlPageIndex.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i + 1)));
        }
        ddlPageIndex.SelectedIndex = currentPageIndex;
        pgNdx.CurrentPageIndex = currentPageIndex;
        btnGoBack.Enabled = !pgNdx.IsFirstPage;         // ถ้าหากเป็นหน้าแรกให้ disable ปุ่ม Back
        btnGoNext.Enabled = !pgNdx.IsLastPage;         // ถ้าหากเป็นหน้าสุดท้ายให้ disable ปุ่ม Next
        DataList1.DataSource = pgNdx;
        DataList1.DataBind();
}

VB
Private Sub BindControl()
        '-- ...
        '-- อ่านข้อมูลจากฐานข้อมูล มาใส่ไว้ใน DataTable
        '-- ...
        Dim pgNdx As New PagedDataSource()
        pgNdx.DataSource = dv        '-- Bind DataView ให้กับ PageDataSource object
        pgNdx.PageSize = 5             '-- กำหนดจำนวนรายการที่ต้องการให้แสดงในแต่ละหน้า
        pgNdx.AllowPaging = True    '-- กำหนดว่าให้มีการทำ paging ได้

        ddlPageIndex.Items.Clear()   '-- เพิ่มจำนวนหน้าลงใน DropDownList Control
        For i As Integer = 0 To (pgNdx.PageCount - 1)
            ddlPageIndex.Items.Add(New ListItem(Convert.ToString(i + 1), Convert.ToString(i + 1)))
        Next
        ddlPageIndex.SelectedIndex = currentPageIndex
        pgNdx.CurrentPageIndex = currentPageIndex
        btnGoBack.Enabled = Not (pgNdx.IsFirstPage)         '-- ถ้าหากเป็นหน้าแรกให้ disable ปุ่ม Back
        btnGoNext.Enabled = Not (pgNdx.IsLastPage)        
'-- ถ้าหากเป็นหน้าสุดท้ายให้ disable ปุ่ม Next
        DataList1.DataSource = pgNdx
        DataList1.DataBind()
End Sub

จากนั้นมาจัดการกับการเปลี่ยนหน้าเมื่อมีการกดปุ่ม Back และ Next
C#
void btnGoBack_Click(object sender, EventArgs e) {
        currentPageIndex -= 1;
        BindControl();
}
void btnGoNext_Click(object sender, EventArgs e) {
        currentPageIndex += 1;
        BindControl();
}

VB
Protected Sub btnGoBack_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGoBack.Click
        currentPageIndex -= 1
        BindControl()
End Sub
Protected Sub btnGoNext_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGoNext.Click
        currentPageIndex += 1
        BindControl()
End Sub

 
เรียบร้อยครับ มาดูผลงานสักหน่อย
 
 
แหล่งข้อมูลดาวน์โหลด
 
แหล่งข้อมูลอ้างอิง


firefly วันที่ส่ง: 15 ต.ค. 52 10:47 GMT+7
วันที่ปรับล่าสุด: 22 ต.ค. 52 23:30 GMT+7
REPLY #1 (115252)
ขอบคุณครับ


nano วันที่ส่ง: 15 ต.ค. 52 13:35 GMT+7
วันที่ปรับล่าสุด: 15 ต.ค. 52 13:35 GMT+7
REPLY #2 (115257)
เป็นประโยชน์มากครับ สามารถใช้ DataList แบบแบ่งหน้า ได้ง่ายขึ้นมากเลย


kop วันที่ส่ง: 15 ต.ค. 52 14:20 GMT+7
วันที่ปรับล่าสุด: 15 ต.ค. 52 14:20 GMT+7
REPLY #3 (115589)
เยี่ยมเลยครับ


sf วันที่ส่ง: 22 ต.ค. 52 14:47 GMT+7
วันที่ปรับล่าสุด: 22 ต.ค. 52 14:47 GMT+7
REPLY #4 (115605)

ขยันจังเลยพี่ริน  

วันนี้ไม่ได้ไปกินข้าวร้านตาชงด้วย เดี๋ยวว่างๆ นัดกันใหม่นะครับ



nas วันที่ส่ง: 22 ต.ค. 52 23:30 GMT+7
วันที่ปรับล่าสุด: 22 ต.ค. 52 23:30 GMT+7

ตอบข้อความ/ร่วมแสดงความคิดเห็น

กรุณา Sign In / เข้าสู่ระบบ เพื่อโพสต์หรืออ่านข้อความ
ยังไม่ได้สมัครสมาชิก? Sign Up / สมัครสมาชิกใหม่
8 ก.ย. 19:41
Online: 173