我正在使用自定义寻呼机构建自定义ASP.Net gridview服务器控件(而非用户控件)。自定义寻呼机包含一个动态添加的下拉列表,用于更改gridview的pagesize(每页项目数)。下拉列表添加在RenderChildren方法中,我将覆盖在服务器控件的代码中。
我基本上是克隆默认的寻呼机行并将下拉列表添加到行中,然后将克隆的寻呼机行添加到gridview并销毁原始行。
问题在于即使dropdownlist的autopostback属性设置为true并且我正在为它添加事件处理程序,我也无法在更改selectedindex时触发事件。我尝试了几种不同的方法,没有运气。
我认为问题在于,在调用页面中更改selectedindex时,尚未呈现下拉列表。但是我对服务器控件和页面生命周期知之甚少,无法弄清楚如何解决它。
以下是代码的缩写版本:
Public Class CustomGridView
Inherits System.Web.UI.WebControls.GridView
Implements IPostBackEventHandler
Protected WithEvents mctlDropdownListPageSize As New DropDownList
Public Event PageSizeChanged(ByVal sender As Object, ByVal e As EventArgs)
Protected Sub dropdownListPageSize_Click(ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent PageSizeChanged(Me.mctlDropdownListPageSize, e)
End Sub
'This sets up paging using the pageddatasource
Protected Overrides Sub InitializePager(row As GridViewRow, columnSpan As Integer, pagedDataSource As PagedDataSource)
pagedDataSource.AllowPaging = True
pagedDataSource.AllowCustomPaging = True
pagedDataSource.VirtualCount = TotalRows
pagedDataSource.CurrentPageIndex = CurrentPageIndex
Me.PageIndex = CurrentPageIndex
MyBase.InitializePager(row, columnSpan, pagedDataSource)
End Sub
Protected Overrides Sub RenderChildren(writer As HtmlTextWriter)
Try
If Me.Controls.Count = 0 Then
' nothing to render, use default
MyBase.RenderChildren(writer)
Return
End If
' select the header row in the grid
Dim gridViewTable As WebControl = DirectCast(Me.Controls(0), WebControl) ' the table
' the table->row(0) if no top paging, otherwise row(1)
Dim pagerRow As GridViewRow = gridViewTable.Controls(0)
'Get the pager cell -- we want only one cell containing all the elements
Dim pagerContainerCell As TableCell = pagerRow.Cells(0)
'Create the new table which will contain the title, results summary and pager
Dim newPagerTable As New Table
newPagerTable.CellPadding = 0
newPagerTable.CellSpacing = 0
newPagerTable.CssClass = "section_headers gridpagertable"
'Create a table row to contain the new cells
Dim newPagerRow As New TableRow
newPagerRow.CssClass = "pagerrow"
'Create 2 cells to hold the new controls + pager
Dim resultsCell As New TableCell
resultsCell.CssClass = "results"
Dim pagerCell As New TableCell
pagerCell.CssClass = "pager"
If Me.AllowPaging Then
'Add the pagesize dropdown and results summary text
'Create the results label
Dim mctlResultsLabelText As New LiteralControl
mctlResultsLabelText.Text = "<span>Results per page </span>"
'Create the pagesize dropdown container div
Dim mctlResultsDropdownListContainerDiv As New HtmlControls.HtmlGenericControl("div")
mctlResultsDropdownListContainerDiv.Attributes("class") = "dropdown_select"
Dim mctlResultsDropdownListLabel As New HtmlControls.HtmlGenericControl("label")
'Create the pagesize dropdownlist
mctlDropdownListPageSize.ID = "dropDownListPageSize"
mctlDropdownListPageSize.Items.Add(New ListItem("100", "100"))
mctlDropdownListPageSize.Items.Add(New ListItem("200", "200"))
mctlDropdownListPageSize.Items.Add(New ListItem("300", "300"))
mctlDropdownListPageSize.AutoPostBack = True
mctlDropdownListPageSize.EnableViewState = True
AddHandler mctlDropdownListPageSize.SelectedIndexChanged, AddressOf Me.dropdownListPageSize_Click
'Add the dropdown tot he dropdown container div
mctlResultsDropdownListLabel.Controls.Add(mctlDropdownListPageSize)
mctlResultsDropdownListContainerDiv.Controls.Add(mctlResultsDropdownListLabel)
'Add the results drpdown label
resultsCell.Controls.Add(mctlResultsLabelText)
'Add the pagesize dropdown
resultsCell.Controls.Add(mctlResultsDropdownListContainerDiv)
'Add the cell to the row
newPagerRow.Controls.Add(resultsCell)
End If
'Add the pager control and action icons
Dim mctlPagerContainerDiv As New HtmlControls.HtmlGenericControl("div")
mctlPagerContainerDiv.Attributes.Add("class", "pagination")
'Add the div to the pager cell
pagerCell.Controls.Add(mctlPagerContainerDiv)
If Me.AllowPaging Then
'Get the existing pager container table with the pager buttons
Dim tblPager As Table
tblPager = pagerContainerCell.Controls(0)
tblPager.CellPadding = 0
'Add the pager to the cell
pagerCell.Controls.Add(tblPager)
End If
'Add the cell to the row
newPagerRow.Controls.Add(pagerCell)
'Add the row to the table
newPagerTable.Controls.Add(newPagerRow)
'Render the new pager row (table+row+3 new cells with controls)
newPagerTable.RenderControl(writer)
If Me.AllowPaging Then
' remove the original (default) pager row, otherwise we have two
gridViewTable.Controls.RemoveAt(0)
End If
'Render the gridview
gridViewTable.RenderControl(writer)
Catch ex As Exception
ControlErrorHandler(ex, "RenderChildren")
End Try
End Sub
Private Sub ControlErrorHandler(ByVal ex As Exception, ByVal methodName As String)
Throw New ApplicationException(Me.GetType().ToString & "." & methodName & " failed due to the inner error - " & ex.Message, ex)
End Sub
<Description("The current page index of the gridview."), DefaultValue(""), Themeable(False), Category("Appearance")> _
Public Property CurrentPageIndex() As Integer
Get
If Not ViewState(VSKeyCurrPageIndex) Is Nothing Then
Return Integer.Parse(ViewState(VSKeyCurrPageIndex))
Else
Return 0
End If
End Get
Set(value As Integer)
ViewState(VSKeyCurrPageIndex) = value
End Set
End Property
End Class
调用页面包含:
Private Sub gridViewResults_PageSizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles gridViewResults.PageSizeChanged
'
End Sub
我已经在Stackoverflow上查看了几乎所有相关问题,以及帖子和文章在线的其他可能的解决方案。任何见解或建议将不胜感激。