@DotNetDaddyに同意します。これは、データソースをポストバックに設定する必要があるという点です。これが、死の「楽しい」黄色い画面の理由であることがほぼ確実です。以下は、.NET2.0以降でのGridViewの並べ替えとページングを示す非常に単純な例です。
以下は、このグリッドビューが私のvbコードで正しく機能するために必要な正確なマークアップです。
<asp:GridView ID="gridSuppliers" EnableViewState="false" runat="server" OnPageIndexChanging="gridSuppliers_PageIndexChanging" AutoGenerateColumns="false" AllowPaging="true" AllowSorting="true" CssClass="datatable" CellPadding="0" CellSpacing="0" BorderWidth="0" GridLines="None">...</asp:GridView>
次は、コレクションベースのデータバインドに必要な並べ替え/ページングの実装を含むコードビハインドファイルです。
Partial Public Class _Default
Inherits System.Web.UI.Page
Implements ISupplierView
Private presenter As SupplierPresenter
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
presenter = New SupplierPresenter(Me)
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
presenter.OnViewLoad()
End Sub
Protected Sub gridSuppliers_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles gridSuppliers.PageIndexChanging
gridSuppliers.PageIndex = e.NewPageIndex
presenter.PopulateSupplierList()
End Sub
Private Sub gridSuppliers_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs) Handles gridSuppliers.Sorting
If DirectCast(ViewState("PreviousSortExpression"), String) = e.SortExpression Then
If DirectCast(ViewState("PreviousSortDirection"), String) = "Ascending" Then
e.SortDirection = System.Web.UI.WebControls.SortDirection.Descending
ViewState("PreviousSortDirection") = "Descending"
Else
e.SortDirection = System.Web.UI.WebControls.SortDirection.Ascending
ViewState("PreviousSortDirection") = "Ascending"
End If
Else
e.SortDirection = System.Web.UI.WebControls.SortDirection.Ascending
ViewState("PreviousSortDirection") = "Ascending"
End If
ViewState("PreviousSortExpression") = e.SortExpression
Dim gv As GridView = DirectCast(sender, GridView)
If e.SortExpression.Length > 0 Then
For Each field As DataControlField In gv.Columns
If field.SortExpression = e.SortExpression Then
ViewState("PreviousHeaderIndex") = gv.Columns.IndexOf(field)
Exit For
End If
Next
End If
presenter.PopulateSupplierList()
End Sub
#Region "ISupplierView Properties"
Private ReadOnly Property PageIsPostBack() As Boolean Implements ISupplierView.PageIsPostBack
Get
Return Page.IsPostBack
End Get
End Property
Private ReadOnly Property SortExpression() As String Implements ISupplierView.SortExpression
Get
If ViewState("PreviousSortExpression") Is Nothing Then
ViewState("PreviousSortExpression") = "CompanyName"
End If
Return DirectCast(ViewState("PreviousSortExpression"), String)
End Get
End Property
Public ReadOnly Property SortDirection() As String Implements Library.ISupplierView.SortDirection
Get
If ViewState("PreviousSortDirection") Is Nothing Then
ViewState("PreviousSortDirection") = "Ascending"
End If
Return DirectCast(ViewState("PreviousSortDirection"), String)
End Get
End Property
Public Property Suppliers() As System.Collections.Generic.List(Of Library.Supplier) Implements Library.ISupplierView.Suppliers
Get
Return DirectCast(gridSuppliers.DataSource(), List(Of Supplier))
End Get
Set(ByVal value As System.Collections.Generic.List(Of Library.Supplier))
gridSuppliers.DataSource = value
gridSuppliers.DataBind()
End Set
End Property
#End Region
End Class
そして最後に、コードビハインドで使用されるプレゼンタークラス
Public Class SupplierPresenter
Private mView As ISupplierView
Private mSupplierService As ISupplierService
Public Sub New(ByVal View As ISupplierView)
Me.New(View, New SupplierService())
End Sub
Public Sub New(ByVal View As ISupplierView, ByVal SupplierService As ISupplierService)
mView = View
mSupplierService = SupplierService
End Sub
Public Sub OnViewLoad()
If mView.PageIsPostBack = False Then
PopulateSupplierList()
End If
End Sub
Public Sub PopulateSupplierList()
Try
Dim SupplierList As List(Of Supplier) = mSupplierService.GetSuppliers()
SupplierList.Sort(New GenericComparer(Of Supplier)(mView.SortExpression, mView.SortDirection))
mView.Suppliers = SupplierList
Catch ex As Exception
Throw ex
End Try
End Sub
End Class
**プレゼンターで参照されるジェネリックコレクションをソートするために必要なクラス
Imports System.Reflection
Imports System.Web.UI.WebControls
Public Class GenericComparer(Of T)
Implements IComparer(Of T)
Private mDirection As String
Private mExpression As String
Public Sub New(ByVal Expression As String, ByVal Direction As String)
mExpression = Expression
mDirection = Direction
End Sub
Public Function Compare(ByVal x As T, ByVal y As T) As Integer Implements System.Collections.Generic.IComparer(Of T).Compare
Dim propertyInfo As PropertyInfo = GetType(T).GetProperty(mExpression)
Dim obj1 As IComparable = DirectCast(propertyInfo.GetValue(x, Nothing), IComparable)
Dim obj2 As IComparable = DirectCast(propertyInfo.GetValue(y, Nothing), IComparable)
If mDirection = "Ascending" Then
Return obj1.CompareTo(obj2)
Else
Return obj2.CompareTo(obj1)
End If
End Function
End Class