• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

[VB.NET] Hướng dẫn phân trang trong DataGridView

Các bài viết hướng dẫn về Visual Basic .NET và C#

Điều hành viên: tungcan5diop, QUANITGROBEST

Hình đại diện của người dùng
Kasper
Guru
Guru
Bài viết: 1062
Ngày tham gia: T.Sáu 16/05/2008 10:54 am
Has thanked: 2 time
Been thanked: 76 time
Liên hệ:

[VB.NET] Hướng dẫn phân trang trong DataGridView

Gửi bàigửi bởi Kasper » T.Năm 08/04/2010 10:16 am

Tên bài viết: Hướng dẫn phân trang trong DataGridView
Tác giả: Kasper
Cấp độ bài viết: Chưa đánh giá
Tóm tắt:



Bài viết này sẽ hướng dẫn các bạn phân trang cho DataGridView.
Cần: 1 form, 1 datagridview, 3 button: btnLoad, btnBack, btnNext. 1 Label: lblPage: hiển thị" "trang hiện tại/tổng số trang"

Khai báo các biến liên quan
  1.     Dim mCurrentPage As Integer ' Trang hiện tại
  2.     Dim mNumPages As Integer ' Tổng số trang
  3.     Const ITEMperPAGE As Integer = 15 ' Số Item cần hiển thị trên một trang
  4.  


Để có dữ liệu thao tác tui sẽ giả lập dữ liệu, phần này các bạn thay thế bằng dữ liệu của mình được truy vấn từ csdl.
Code trong btnLoad
  1.     Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click
  2.         ' Giả lập dữ liệu
  3.         Dim dt As New DataTable
  4.         dt.Columns.Add("STT")
  5.         dt.Columns.Add("Name")
  6.         dt.Columns.Add("Date")
  7.         Dim i As Integer
  8.         For i = 1 To 107
  9.             dt.Rows.Add(i, "Tran Van " & Chr(i + 64), Format(Now.Date.AddDays(i), "dd/MM/yyyy"))
  10.         Next
  11.         ' Cho hiển thị trang đầu tiên, ở đây tui hiển thị 15 item/1 trang.
  12.         ' Ta sẽ dùng method RowFilter của DataTable để lọc dữ liệu hiển thị
  13.         ' Tui sẽ dựa vào cột STT để xét điều kiện lọc, các bạn có thể thay thế theo ý mình.
  14.         DataGridView1.DataSource = dt
  15.         mCurrentPage = 1
  16.         mNumPages = Math.Round(dt.Rows.Count / ITEMperPAGE + 0.5) ' Xác định tổng số trang cần chia
  17.         lblPage.Text = "1/" & mNumPages
  18.         Dim gridTable As DataTable = CType(DataGridView1.DataSource, DataTable)
  19.         gridTable.DefaultView.RowFilter = "STT <= " & ITEMperPAGE * mCurrentPage ' Lọc phân trang theo điều kiện.
  20.         btnNext.Enabled = True
  21.     End Sub
  22.  


Xong phần giả lập dữ liệu và hiển thị trang đầu tiên, giờ ta sẽ viết code cho nút Next và Back.
1. Nút Next: mỗi lần click, ta sẽ tăng trang hiện tại lên 1, xét xem trang hiện tại còn <= tổng số trang hay không, nếu đúng ta tiến hành lọc dữ liệu.
  1.     Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click
  2.         mCurrentPage += 1
  3.         If mCurrentPage <= mNumPages Then
  4.             Dim gridTable As DataTable = CType(DataGridView1.DataSource, DataTable)
  5.             gridTable.DefaultView.RowFilter = "STT > " & ITEMperPAGE * (mCurrentPage - 1) & " AND STT <= " & ITEMperPAGE * mCurrentPage
  6.             btnBack.Enabled = True
  7.             lblPage.Text = mCurrentPage & "/" & mNumPages
  8.         End If
  9.         If mCurrentPage = mNumPages Then
  10.             btnBack.Enabled = True
  11.             btnNext.Enabled = False
  12.         End If
  13.     End Sub
  14.  


2. Nút Back: mỗi lần click, ta sẽ giảm trang hiện tại xuống 1, xét xem trang hiện tại còn >= trang đầu tiên hay không, nếu đúng ta tiến hành lọc dữ liệu.
  1.     Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
  2.         mCurrentPage -= 1
  3.         If mCurrentPage >= 1 Then
  4.             Dim gridTable As DataTable = CType(DataGridView1.DataSource, DataTable)
  5.             gridTable.DefaultView.RowFilter = "STT > " & ITEMperPAGE * (mCurrentPage - 1) & " AND STT <= " & ITEMperPAGE * mCurrentPage
  6.             btnNext.Enabled = True
  7.             lblPage.Text = mCurrentPage & "/" & mNumPages
  8.         End If
  9.         If mCurrentPage = 1 Then
  10.             btnBack.Enabled = False
  11.             btnNext.Enabled = True
  12.         End If
  13.     End Sub
  14.  


Chúc các bạn thành công!
Tập tin đính kèm
Chiatrang.gif
Chiatrang.zip
(69.82 KiB) Đã tải 1932 lần


Lành tợ tòng, ác tợ hoa,
Nhà hòa muôn việc đều nên.

amrsau
Bài viết: 1
Ngày tham gia: T.Sáu 09/07/2010 4:22 pm

Re: [VB.NET] Hướng dẫn phân trang trong DataGridView

Gửi bàigửi bởi amrsau » T.Sáu 09/07/2010 9:53 pm

Bài này vẫn hơi lỗi 1 tý!

Nếu khi ấn vào load xong,bạn cứ click vào nút back vài cái xem sao?Sau đó bạn click vào nút nẽt và xem kết quả trên trang hiển thị!

Đây là ý kiến của mình:Bạn nên để btnBack.Enable=false khi Load và khi click vào Next thì btnBack.enable=true

Hình đại diện của người dùng
Kasper
Guru
Guru
Bài viết: 1062
Ngày tham gia: T.Sáu 16/05/2008 10:54 am
Has thanked: 2 time
Been thanked: 76 time
Liên hệ:

Re: [VB.NET] Hướng dẫn phân trang trong DataGridView

Gửi bàigửi bởi Kasper » T.Hai 12/07/2010 11:58 am

amrsau đã viết:Bài này vẫn hơi lỗi 1 tý!

Nếu khi ấn vào load xong,bạn cứ click vào nút back vài cái xem sao?Sau đó bạn click vào nút nẽt và xem kết quả trên trang hiển thị!

Đây là ý kiến của mình:Bạn nên để btnBack.Enable=false khi Load và khi click vào Next thì btnBack.enable=true


Cái này có rồi mà. Vừa load xong làm gì bấm được nút Back khi nó Disable mà lỗi hả bạn? :-/
Lành tợ tòng, ác tợ hoa,
Nhà hòa muôn việc đều nên.

Hình đại diện của người dùng
vuathongtin
Điều hành viên
Điều hành viên
Bài viết: 1028
Ngày tham gia: CN 02/05/2010 10:03 pm
Đến từ: Xứ sở DG
Has thanked: 2 time
Been thanked: 105 time
Liên hệ:

Re: [VB.NET] Hướng dẫn phân trang trong DataGridView

Gửi bàigửi bởi vuathongtin » T.Ba 13/07/2010 9:46 am

Mình xin góp ý 1 chút nhen .
1. Bạn nên đưa biến datatable khai báo tạm : lên làm biến toàn cục
Khi đó :
Next :
  1. If mCurrentPage < mNumPages Then
  2.             mCurrentPage += 1
  3.             lblPage.Text = mCurrentPage & "/" & mNumPages
  4.           gridTable.DefaultView.RowFilter = "STT>" & ITEMperPAGE * (mCurrentPage - 1) & " and STT<=" & ITEMperPAGE * mCurrentPage & ""
  5.         End If


Back :
  1.  If mCurrentPage > 1 Then
  2.             mCurrentPage -= 1
  3.             lbl_page.Text = mCurrentPage & "/" & mNumPages
  4.             gridTable.DefaultView.RowFilter = "STT>" & ITEMperPAGE * (mCurrentPage - 1) & " and STT<=" & ITEMperPAGE * mCurrentPage & ""
  5.  
  6.         End If


Ví dụ : Code phân trang trong Project của mình :

  1. Imports System.Data.OleDb
  2.  
  3. Public Class frm_dssinhvien
  4.     Dim mCurrentPage As Integer
  5.     Dim mNumPages As Integer
  6.     Const ITEMperPAGE As Integer = 7
  7.  
  8.     Dim con As New OleDbConnection
  9.     Dim da_sinhvien As New OleDbDataAdapter
  10.     Dim dt_sinhvien As New DataTable
  11.  
  12.     Public dt_temp As DataTable
  13.  
  14.     Sub ketnoi()
  15.         If con.State = ConnectionState.Closed Then
  16.             con.ConnectionString = "Provider=Microsoft.Jet.OleDB.4.0;" & "data source=" & Application.StartupPath & "\QUAN_LY_SINH_VIEN.mdb"
  17.             con.Open()
  18.         End If
  19.     End Sub
  20.  
  21.     Private Sub frm_dssinhvien_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  22.         ketnoi()
  23.         da_sinhvien = New OleDbDataAdapter("Select *from SINHVIEN", con)
  24.         da_sinhvien.Fill(dt_sinhvien)
  25.         dgv_sinhvien.DataSource = dt_sinhvien
  26.  
  27.         dt_sinhvien.Columns.Add("STT")
  28.         For i As Integer = 0 To dt_sinhvien.Rows.Count - 1
  29.             dgv_sinhvien.Rows(i).Cells("STT").Value = i
  30.         Next
  31.  
  32.         ' Tinh so trang can chia
  33.         mCurrentPage = 1
  34.         mNumPages = Math.Round(dt_sinhvien.Rows.Count / ITEMperPAGE + 0.5)
  35.         lbl_page.Text = "1/" & mNumPages
  36.  
  37.         dt_temp = (CType(dgv_sinhvien.DataSource, DataTable))
  38.         dt_temp.DefaultView.RowFilter = "STT<=" & ITEMperPAGE * mCurrentPage & ""
  39.     End Sub
  40.  
  41.     Private Sub btn_next_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_next.Click
  42.         If mCurrentPage < mNumPages Then
  43.             mCurrentPage += 1
  44.             lbl_page.Text = mCurrentPage & "/" & mNumPages
  45.             dt_temp.DefaultView.RowFilter = "STT>" & ITEMperPAGE * (mCurrentPage - 1) & " and STT<=" & ITEMperPAGE * mCurrentPage & ""
  46.         End If
  47.     End Sub
  48.  
  49.     Private Sub btn_previous_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_previous.Click
  50.         If mCurrentPage > 1 Then
  51.             mCurrentPage -= 1
  52.             lbl_page.Text = mCurrentPage & "/" & mNumPages
  53.             dt_temp.DefaultView.RowFilter = "STT>" & ITEMperPAGE * (mCurrentPage - 1) & " and STT<=" & ITEMperPAGE * mCurrentPage & ""
  54.  
  55.         End If
  56.     End Sub
  57. End Class
  58.  



Mình xin nếu tóm lược các bước để phân trang trong datagridview để các bạn dễ hình dung:
1. Khai báo các biến toàn cục sau :
  1.  Dim mCurrentPage As Integer ' vị trí trang hiện tại
  2.  Dim mNumPages As Integer ' số trang = tổng số record (= dt.row.count) / số record cần hiển thị
  3. Const ITEMperPAGE As Integer = 7 'Số Record cần hiển thị ở mỗi trang
  4. dim dt_temp As DataTable ' biến datatable (tạm) dùng để hiển thị phân trang trong datagrid
  5.  

2. Tính số trang cần chia
  1.         mCurrentPage = 1
  2.         mNumPages = Math.Round(dt_sinhvien.Rows.Count / ITEMperPAGE + 0.5) 'Dùng toán tử Round để làm tròn số


3.
3.1 (Bước này không cần thiết)
Add thêm cột "STT" để lọc số record cần hiển thị
  1. dt.Columns.Add("STT")
  2.         For i As Integer = 0 To dt.Rows.Count - 1
  3.             datagridview1.Rows(i).Cells("STT").Value = i
  4.         Next


3.2.
Chuyển dữ liệu từ Datagridview vào biến dt_temp
bằng hàm Ctype
  1.    dt_temp = (CType(datagridview1.DataSource, DataTable))


4. Dùng phương thức RowFilter để Show dữ liệu với điều kiện cho trước
dt_temp.DefaultView.RowFilter = "STT<=" & ITEMperPAGE * mCurrentPage & ""

Khi next (hoăc Back):

1. Tăng (hoặc giảm) vị trí trang hiện tại lên 1
Dùng phương thức Rowfilter để hiển thị dữ liệu với điều kiện
STT>" & ITEMperPAGE * (mCurrentPage - 1) & " and STT<=" & ITEMperPAGE * mCurrentPage &

2. Tạo các điều kiện ràng buộc khi Next (hoặc Back)
Next : khi giá trị trang hiện tại < số trang :

Mã: Chọn hết

 mCurrentPage < mNumPages

Back : chỉ khi nào giá trị trang hiện tại > 1 :

Mã: Chọn hết

mCurrentPage > 1
Tập tin đính kèm
QLSV.rar
(71.61 KiB) Đã tải 672 lần
Sửa lần cuối bởi vuathongtin vào ngày T.Ba 13/07/2010 10:16 am với 1 lần sửa.
Bùi Thành Nhân
CNTT-Sở Thông tin & Truyền thông tỉnh Phú Yên
giasulaptrinh.com
Skype:vuathongtin

Hình đại diện của người dùng
thuccads
Thành viên tích cực
Thành viên tích cực
Bài viết: 143
Ngày tham gia: T.Hai 01/02/2010 8:35 am
Đến từ: Hà Nội--->Sài Gòn
Been thanked: 1 time
Liên hệ:

Re: [VB.NET] Hướng dẫn phân trang trong DataGridView

Gửi bàigửi bởi thuccads » T.Ba 13/07/2010 10:06 am

Nếu SQL 2005 trở lên thì bạn dùng hàm ROW_NUMBER() đỡ phải Add columns.

Hình đại diện của người dùng
Kasper
Guru
Guru
Bài viết: 1062
Ngày tham gia: T.Sáu 16/05/2008 10:54 am
Has thanked: 2 time
Been thanked: 76 time
Liên hệ:

Re: [VB.NET] Hướng dẫn phân trang trong DataGridView

Gửi bàigửi bởi Kasper » T.Ba 13/07/2010 11:21 am

Mình xin góp ý 1 chút nhen .
1. Bạn nên đưa biến datatable khai báo tạm lên làm biến toàn cục


Biến toàn cục hay biến cục bộ chỗ này chúng ta nên suy xét kỹ hơn.
1. Biến cục bộ:
Mỗi lần click nút back hoặc next: lấy datasource của DGV đổ vào datatable, tốc độ của thao tác này nhanh chậm tùy thuộc vào số row nhiều hay ít, nhưng được lợi là thoát khỏi hàm thì giải phóng luôn bộ nhớ.
Có ai test giùm câu lệnh sau đây mất bi nhiêu time với số lượng row khác nhau: 1K, 10K, 100K, 1.000K, ...
  1. Dim gridTable As DataTable = CType(DataGridView1.DataSource, DataTable)
  2.  


2. Biến toàn cục:
Chỉ lấy datasource 1 lần duy nhất, nhưng chương trình sẽ chiếm nhiều bộ nhớ để lưu trữ datatable cho đến khi đóng form này lại.

Vậy nếu để tối ưu chương trình, ta nên cân nhắc kỹ rồi sử dụng thôi :D
Lành tợ tòng, ác tợ hoa,
Nhà hòa muôn việc đều nên.


Quay về “[.NET] Bài viết hướng dẫn”

Đang trực tuyến

Đang xem chuyên mục này: Không có thành viên nào trực tuyến.0 khách