Phân trang trong winform | Paging in winform

Đăng bởi : 6/13/2014

thuvienwinform - Phân trang thực ra là một đặc trưng trong lập trình web. Chia dữ liệu cần tải (load) ra làm nhiều phần nhỏ giúp việc hiển thị nhanh hơn (do dữ liệu tải về nhỏ hơn). Trong winform thì phân trang giúp cho sử dụng tài nguyên (cụ thể là RAM) ít hơn. Nhưng mình thử thì không giảm đi là bao :)), có lẽ do mình chưa giải phòng bộ nhớ tốt.




Sau đây mình xin giới thiệu với các bạn phân trang trong winform đằng LINQToSQL

Thư viện phân trang: https://www.dropbox.com/s/nj6fnuso2b2138p/ThuVienWinform.PhanTrang.dll (14KB)
Chương trình mẫu: https://www.dropbox.com/s/z9dvnbtceu3xv40/ThuVienWinform-PhanTrangLINQ.rar (710KB)

Nếu không tải được trên DropBox các bạn liên hệ trực tiếp thuvienwinform@gmail.com để mình gửi hoặc chạy Ultrasuft để truy cập lại DropBox

Trong chương trình mẫu có 2 tệp tin chứa cơ sở dữ liệu cho nó chạy các bạn nạp nó vào rồi sửa lại kết nối cho LINQ mới chạy được

Giới thiệu ThuVienWinform.PhanTrang:
- Với thư viện này sẽ không làm ảnh hưởng đến mã đã viết vì không cần thêm dòng code nào cả, chỉ việc khai báo và xài thui
- Khai báo:
phanTrang = new PhanTrangTruyenThong<tbPhanTrang>(this.db, this.bindingNavigator1, 20);
Hoặc
PhanTrangTuyChinh<tbPhanTrang> pTrang = new PhanTrangTuyChinh<tbPhanTrang>(this.db, button1, comboBox1, button2, bindingNavigator1.BindingSource, 20);
Trong đó:
+ tbPhanTrang là đối tượng cần phân trang, ở đây là một bảng tbPhanTrang trong CSDL
+ db là biến DataContext của LINQToSQL
+ bindingNavigator1: thanh điều hướng cho datagridView
+ 20: số hàng trên 1 trang
+ button1: là nút nhảy về trang sau
+ button2: là nút nhảy về trang trước
+ comboBox1: là comboBox để hiển thị các trang
+ bindingNagigator1.BindingSource là BindingSource của datagridView

- Chế độ:
+ PhanTrangTruyenThong: phân trang dựa vào bindingNavigator có sẵn, mình sẽ thêm 2 nút tiến lùi và 2 cái comboBox để hiển thị số trang lên đó
+ PhanTrangTuyChinh: truyền vào 2 nút và 1 comboBox có sẵn để làm 2 nút tiến lùi và hiển thị danh sách trang.

- Thuộc tính và sự kiện:
+ TrangHienTai: lấy về hoặc đặt trang hiện tại (set, get)
+ sự kiện NhayTrang: trả về hướng nhảy (tiến hoặc lùi) và số trang nhảy

- Mã phân trang bằng LINQ
 
/// <summary>
/// Lấy dữ liệu từ chiSoDau đến chiSoCuoi
/// </summary>
/// <typeparam name="doiTuongCanPhanTrang">Đối tượng cần phân trang</typeparam>
/// <param name="db">DataContext chứa dữ liệu cần phân trang</param>
/// <param name="chiSoDau">Chỉ số đầu</param>
/// <param name="chiSoCuoi">Chỉ số cuối</param>
/// <returns></returns>
public object DuLieuPhanTrang<doiTuongCanPhanTrang>(DataContext db, int chiSoDau, int chiSoCuoi) where doiTuongCanPhanTrang : class
{
    try
    {
        var phanTrangs = (from p in db.GetTable<doiTuongCanPhanTrang>()
                            select p).Skip(chiSoDau).Take(chiSoCuoi - chiSoDau);
        return phanTrangs;
    }
    catch
    {
        return null;
    }
}

- Tư tưởng phân trang theo mình hiểu như sau: có một kho dữ liệu lớn (ví dụ 10 tỷ trường), ta không tải hết 10 tỷ trường đấy về để hiển thị lên dataGridView được (cháy máy mà chết mất). Nên phải chia nhỏ ra mỗi lần hiển thị 10 nghìn cái thôi!
- Có lỗi về thư viện hoặc ý tưởng mới về phân trang cùng nhau chia sẻ các bạn nha
- Chia sẻ mã ThuVienWinform.PhanTrang.dll quan hòm thư thuvienwinform@gmail.com nha!


{ 10 comments }

  1. thực hiện thêm (Add Reference) System.Data.Linq để sử dụng DataContext nhé!

    ReplyDelete
  2. Cứ tưởng phân trang trực tiếp trên Database (dùng partitioning hoặc indexes) chứ kiểu này là dùng code để chia các record thành các trang hử??? \o/

    ReplyDelete
    Replies
    1. phân trực tiếp trên database không biết@! Cách này chỉ được cái hiển thị, chứ không giảm được tài nguyên sử dụng :(

      Delete
  3. Mình nghĩ là làm kiểu này thì file .dbml nó vẫn load tất cả các record về trước, còn phần code chỉ quyết định xem có bao nhiêu record được in ra, như vậy cộng cả phần xử lý phân trang có khi nó làm chương trình nặng thêm ấy chứ =(

    ReplyDelete
    Replies
    1. mình nghĩ là lúc truy vấn mới bắt đầu tải dữ liệu về...nếu file .dbml tải về hết thì việc truy vấn chỉ có tác dụng chọn dữ liệu thui sao...

      Delete
    2. e nghĩ như Nhận đại ka

      Delete
    3. Theo mình thì cái .dbml chỉ là cái vỏ thui@! Còn lõi (dữ liệu) thì khi nào truy vấn nó mới đổ vào.
      Ví dụ:
      Khi mất kết nối CSDL nhé. Chương trình vẫn chạy bình thường (tức là chưa có cần kết nối CSDL -> chưa tải gì cả).
      Còn khi thực hiện truy vấn mới lỗi (lúc này mới thực hiện kết nối vào tải về)

      Delete
    4. Chiều thử phân trang = ADO.NET xem nhẹ hơn ko!

      Delete
    5. Không có cái LINQToSQL chác nhẹ hơn nhưng binding, thêm, sửa, xóa hơi nản@@!

      Delete
    6. Làm bài phân vùng (partitionning) trên db đi, t đọc mấy bài vẫn chưa hiểu lắm (tại kém sql mà :D )

      Delete

Nhận ngay 100$ cho VPS

Mua hàng ủng hộ page

Ủng hộ page

Nhãn

Code (45) Team Foundation Server (17) Database (14) News (14) product (13) toolbox (10) Linq (9) SoftDesign (8) XNA (6) API (5) Project (5) item (4)

- Bản quyền thuộc về Thư Viện WinForm - Giao diện: Metrominimalist - Thiết kế: Johanes Djogan -