ASP.NET DataGridのページングのカスタマイズ
●目的
DataGridは、デフォルトでページング機能を持っている。
しかし、これは、モードが、「[次へ]、[戻る]ページボタン」か、「ページ番号」のどちらかしか持っていない。
ここでは、ページ番号と[次へ]、[戻る]ボタンの両方を設置する方法を説明する。
--------------- こんな感じにしたい ---------------
<前へ 1 2 3 4 5 次へ>
●方法
(1) VisualStudioのデザイナーで通常の方法でページング機能を追加。
モードは「ページ番号」にしておく。
HTMLコードでは次のようになる。
<PagerStyle Font-Size="Small" HorizontalAlign="Center" Mode="NumericPages"></PagerStyle>
(2) VisualStudioのコード編集で以下のとおりプログラムを追加する。
Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated
If (e.Item.ItemType = ListItemType.Pager) Then
Dim pager As TableCell = e.Item.Cells(0)
Dim btnBeforetPage As LinkButton = New LinkButton
AddHandler btnBeforetPage.Click, AddressOf BeforetPageOnCLick
btnBeforetPage.Text = "<前へ"
pager.Controls.AddAt(0, btnBeforetPage)
'体裁を整えるためスペースを空ける
Dim lit1 As Literal = New Literal
lit1.Text = " "
pager.Controls.AddAt(1, lit1)
'体裁を整えるためスペースを空ける
Dim numControls As Integer = pager.Controls.Count
Dim lit2 As Literal = New Literal
lit2.Text = " "
pager.Controls.AddAt(numControls, lit2)
numControls = pager.Controls.Count
Dim btnNextPage As LinkButton = New LinkButton
AddHandler btnNextPage.Click, AddressOf NextPageOnCLick
btnNextPage.Text = "次へ>"
pager.Controls.AddAt(numControls, btnNextPage)
End If
End Sub
Private Sub BeforetPageOnCLick(ByVal sender As Object, ByVal e As System.EventArgs)
If (DataGrid1.CurrentPageIndex > 0) Then '最初のページ以上戻らないように
DataGrid1.CurrentPageIndex = DataGrid1.CurrentPageIndex - 1
DataGrid1Bind() 'データバインド(適宜ご対応ください)
End If
End Sub
Private Sub NextPageOnCLick(ByVal sender As Object, ByVal e As System.EventArgs)
If (DataGrid1.CurrentPageIndex < DataGrid1.PageCount - 1) Then '最後のページ以上進まないように
DataGrid1.CurrentPageIndex = DataGrid1.CurrentPageIndex + 1
DataGrid1Bind() 'データバインド(適宜ご対応ください)
End If
End Sub
●補足
「デリゲートとイベントを使ったコールバックと通知」
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/dnguinet/htm/drguinet05292001.asp
によると、コントロールのイベントハンドラの結び付けは、VB.NETの場合はVB.NETの作法に従うべきとある。(下記参照)
Public Sub New()
myTimer = New Timer()
' we could omit WithEvents from myTimer's declaration and
' use the below line instead:
' AddHandler myTimer.Tick, AddressOf myTimer_Tick
' but since we have WithEvents, all we have to do is
' use the Handles clause when we declare the event-handling method
End Sub
これに従うならば、
(1) [次へ]のボタンコントロールをクラスの変数としてWithEvents付で宣言する。
Protected WithEvents btnNextPage As LinkButton = New LinkButton
(2)これによって、コードエディタの上部のドロップダウンリストにbtnNextPageがリストアップされる。
(3)上記ドロップダウンリストでbtnNextPageを選択し、右の窓でclickイベントハンドラーを選択する。
(4)イベントハンドラー関数を以下のとおり記述する。
Private Sub btnNextPage_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnNextPage.Click
If (DataGrid1.CurrentPageIndex < DataGrid1.PageCount - 1) Then
DataGrid1.CurrentPageIndex = DataGrid1.CurrentPageIndex + 1
DataGrid1Bind() 'データバインド(適宜ご対応ください)
End If
End Sub
とすることで同様の機能が実現可能になるが.....
しかし、なぜか(まだ原因を追究していないが)ページングボタンをグリッドの上下に配置するとうまく動作しない。
●蛇足
ページャコントロール部がDataGridの枠線内に囲まれていていや(格好悪い)という方のために
Sub Page_Load()内で(Page_Load以外のどこでも適当な場所でよいが)
DataGrid1.BorderStyle = BorderStyle.None 'データグリッドの外枠を消す
Sub DataGrid1_ItemCreated内で
Dim pager As TableCell = e.Item.Cells(0)
pager.BorderStyle = BorderStyle.None 'ページャーコントロール部の外枠を消す
とすればよい。
参考資料:
http://www.atmarkit.co.jp/fdotnet/dotnettips/072modpager/modpager.html
|