I cannot reproduce your problem, please post all the relevant code
源代码如下: 这是页面的基类: Public Class Class1 Inherits System.Web.UI.Page Public WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load DataGrid1 = New DataGrid() DataGrid1.EnableViewState = False DataGrid1.AllowPaging = True DataGrid1.AllowSorting = True Dim i As Integer = 0 For i = 0 To Page.Controls.Count - 1 If Page.Controls(i).GetType.Name = "HtmlForm" Then Page.Controls(i).Controls.Add(DataGrid1) Exit For End If Next Me.DrawDataGrid() BindData() End Sub'该函数用来绑定数据 Protected Overridable Sub BindData() Dim dt As New DataTable() dt.Columns.Add("a", System.Type.GetType("System.String")) Dim row As DataRow = dt.NewRow() row.Item("a") = "aaaa" dt.Rows.Add(row) row = dt.NewRow() row.Item("a") = "bbbb" dt.Rows.Add(row) If Not Page.IsPostBack Then row = dt.NewRow() row.Item("a") = "bbbb" dt.Rows.Add(row) row = dt.NewRow() row.Item("a") = "cccc" dt.Rows.Add(row) row = dt.NewRow() row.Item("a") = "dddd" dt.Rows.Add(row) End If DataGrid1.DataSource = dt DataGrid1.DataBind() End Sub'该函数用来画页角 Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated Dim cb As CheckBox If e.Item.ItemType = ListItemType.Pager Then Dim totalPage As New Label() totalPage.Text = "第" & CInt(DataGrid1.CurrentPageIndex + 1) & "页/共" & DataGrid1.PageCount & "页 " e.Item.Cells(0).Controls.AddAt(0, totalPage) Dim gotoPage As New TextBox() gotoPage.Width = New Unit(30) e.Item.Cells(0).Controls.AddAt(1, gotoPage) Dim gotoBtn As New LinkButton() gotoBtn.Text = "GO" e.Item.Cells(0).Controls.AddAt(2, gotoBtn) Dim litSpace As New Literal() litSpace.Text = " " e.Item.Cells(0).Controls.AddAt(3, litSpace) End If End Sub'该函数用来画DataGird的模版列 Protected Sub DrawDataGrid() Dim FirstSort As String Dim Sort As String Dim DHorizontalAlign As String Dim ColumnWidth As String Dim col1 As New TemplateColumn() col1.ItemTemplate = New DataGridTemplate(ListItemType.Item, "CheckBox") DataGrid1.Columns.Add(col1) End Sub Private Class DataGridTemplate Implements ITemplate Dim templateType As ListItemType Dim columnName As String Sub New(ByVal type As ListItemType, ByVal ColName As String) templateType = type columnName = ColName End Sub Sub InstantiateIn(ByVal container As Control) _ Implements ITemplate.InstantiateIn Dim lc As New Literal() Select Case templateType Case ListItemType.Header Case ListItemType.Item Dim cb As New CheckBox() container.Controls.Add(cb) Case ListItemType.EditItem Case ListItemType.Footer End Select End Sub End ClassEnd Class然后随便找个界面,继承class1,就行了
If Not Page.IsPostBack Then ..最好不用在函数里,应当用在page_load中
frankly, I am not clear myself, so don't be confused if you cannot understand what I am going to say, since I am yet to fully understand what is going on:TextBox/CheckBox/RadioButton are special, in that even if you set their EnableViewState to false, they can still keep their state. For example, you can add a button in the form<asp:Button id="Btn" runat="server" Text="Submit" />comment out DataGrid1.AllowPaging = True ==> 'DataGrid1.AllowPaging = Truethen check the first checkbox, then click on Submit button, you can see that the first checkbox is still checked even if you rebind the whole thing!That means, even if you set the DataGrid's EnableViewState to false, the system still records these checkboxes' ViewState. If you don't believe me, open the HTML source in IE, and copy the value of the hidden control __VIEWSTATE to this page and click on "Parse ViewState" button, http://www.wilsondotnet.com/Demos/ViewState.aspxyou will see something like-1360000050 null ArrayList _ctl0:_ctl3:_ctl0 _ctl0:_ctl4:_ctl0 _ctl0:_ctl5:_ctl0 _ctl0:_ctl6:_ctl0 _ctl0:_ctl7:_ctl0and if you check the HTML source code, you will see they are exactly the names for those <input type=checkbox ..>Now, come back to the original question, what if you set DataGrid1.AllowPaging = True, and reduce the number of DataRows to 2? When the DataGrid is bound, everytime a row/cell is added to the control hierarchy, there are some catchupes to do, including invoking the Init/LoadViewState/ProcessPostData/Load event handler/method for the newly added control. So when you check the first checkbox, the check state will be restored along the way.When the Pager row is created/added, the system will know the third row (the Pager) is no longer valid according to the above ViewState, thus throws an exception. If you don't have DataGrid1.AllowPaging = True or have DataGrid1.AllowPaging = FALSE, the third row is never created/added and it will never check if the data is valid or not. Another way to verify is to create a FooterTemplate for DataGridTemplate and set ShowFooter= true, you will see the exact same errorsHow do you fix the problem? I wish you can clear the postdata stuffs, but I cannot find any such method, for now, you can do the following to cheat ASP.NET, :-)DataGrid1 = New DataGrid() DataGrid1.ID = "DataGrid1" + DateTime.Now.ToString()
frankly, I am not clear myself, so don't be confused if you cannot understand what I am going to say, since I am yet to fully understand what is going on:TextBox/CheckBox/RadioButton are special, in that even if you set their EnableViewState to false, they can still keep their state. For example, you can add a button in the form<asp:Button id="Btn" runat="server" Text="Submit" />comment out DataGrid1.AllowPaging = True ==> 'DataGrid1.AllowPaging = Truethen check the first checkbox, then click on Submit button, you can see that the first checkbox is still checked even if you rebind the whole thing!That means, even if you set the DataGrid's EnableViewState to false, the system still records these checkboxes' ViewState. If you don't believe me, open the HTML source in IE, and copy the value of the hidden control __VIEWSTATE to this page and click on "Parse ViewState" button, http://www.wilsondotnet.com/Demos/ViewState.aspxyou will see something like-1360000050 null ArrayList _ctl0:_ctl3:_ctl0 _ctl0:_ctl4:_ctl0 _ctl0:_ctl5:_ctl0 _ctl0:_ctl6:_ctl0 _ctl0:_ctl7:_ctl0and if you check the HTML source code, you will see they are exactly the names for those <input type=checkbox ..>Now, come back to the original question, what if you set DataGrid1.AllowPaging = True, and reduce the number of DataRows to 2? When the DataGrid is bound, everytime a row/cell is added to the control hierarchy, there are some catchupes to do, including invoking the Init/LoadViewState/ProcessPostData/Load event handler/method for the newly added control. So when you check the first checkbox, the check state will be restored along the way.When the Pager row is created/added, the system will know the third row (the Pager) is no longer valid according to the above ViewState, thus throws an exception. If you don't have DataGrid1.AllowPaging = True or have DataGrid1.AllowPaging = FALSE, the third row is never created/added and it will never check if the data is valid or not. Another way to verify is to create a FooterTemplate for DataGridTemplate and set ShowFooter= true, you will see the exact same errorsHow do you fix the problem? I wish you can clear the postdata stuffs, but I cannot find any such method, for now, you can do the following to cheat ASP.NET, :-)DataGrid1 = New DataGrid() DataGrid1.ID = "DataGrid1" + DateTime.Now.ToString()
这是页面的基类:
Public Class Class1
Inherits System.Web.UI.Page Public WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataGrid1 = New DataGrid()
DataGrid1.EnableViewState = False DataGrid1.AllowPaging = True
DataGrid1.AllowSorting = True Dim i As Integer = 0
For i = 0 To Page.Controls.Count - 1
If Page.Controls(i).GetType.Name = "HtmlForm" Then
Page.Controls(i).Controls.Add(DataGrid1)
Exit For
End If
Next Me.DrawDataGrid()
BindData() End Sub'该函数用来绑定数据
Protected Overridable Sub BindData()
Dim dt As New DataTable()
dt.Columns.Add("a", System.Type.GetType("System.String"))
Dim row As DataRow = dt.NewRow()
row.Item("a") = "aaaa"
dt.Rows.Add(row)
row = dt.NewRow()
row.Item("a") = "bbbb"
dt.Rows.Add(row)
If Not Page.IsPostBack Then
row = dt.NewRow()
row.Item("a") = "bbbb"
dt.Rows.Add(row)
row = dt.NewRow()
row.Item("a") = "cccc"
dt.Rows.Add(row)
row = dt.NewRow()
row.Item("a") = "dddd"
dt.Rows.Add(row)
End If
DataGrid1.DataSource = dt
DataGrid1.DataBind() End Sub'该函数用来画页角
Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated
Dim cb As CheckBox
If e.Item.ItemType = ListItemType.Pager Then
Dim totalPage As New Label()
totalPage.Text = "第" & CInt(DataGrid1.CurrentPageIndex + 1) & "页/共" & DataGrid1.PageCount & "页 "
e.Item.Cells(0).Controls.AddAt(0, totalPage)
Dim gotoPage As New TextBox()
gotoPage.Width = New Unit(30)
e.Item.Cells(0).Controls.AddAt(1, gotoPage)
Dim gotoBtn As New LinkButton()
gotoBtn.Text = "GO"
e.Item.Cells(0).Controls.AddAt(2, gotoBtn)
Dim litSpace As New Literal()
litSpace.Text = " "
e.Item.Cells(0).Controls.AddAt(3, litSpace)
End If
End Sub'该函数用来画DataGird的模版列
Protected Sub DrawDataGrid()
Dim FirstSort As String
Dim Sort As String
Dim DHorizontalAlign As String
Dim ColumnWidth As String
Dim col1 As New TemplateColumn()
col1.ItemTemplate = New DataGridTemplate(ListItemType.Item, "CheckBox")
DataGrid1.Columns.Add(col1)
End Sub
Private Class DataGridTemplate
Implements ITemplate
Dim templateType As ListItemType
Dim columnName As String Sub New(ByVal type As ListItemType, ByVal ColName As String)
templateType = type
columnName = ColName
End Sub Sub InstantiateIn(ByVal container As Control) _
Implements ITemplate.InstantiateIn
Dim lc As New Literal()
Select Case templateType
Case ListItemType.Header
Case ListItemType.Item
Dim cb As New CheckBox()
container.Controls.Add(cb)
Case ListItemType.EditItem
Case ListItemType.Footer
End Select
End Sub
End ClassEnd Class然后随便找个界面,继承class1,就行了
DataGrid1.AllowPaging = True
==>
'DataGrid1.AllowPaging = Truethen check the first checkbox, then click on Submit button, you can see that the first checkbox is still checked even if you rebind the whole thing!That means, even if you set the DataGrid's EnableViewState to false, the system still records these checkboxes' ViewState. If you don't believe me, open the HTML source in IE, and copy the value of the hidden control __VIEWSTATE to this page and click on "Parse ViewState" button, http://www.wilsondotnet.com/Demos/ViewState.aspxyou will see something like-1360000050
null
ArrayList
_ctl0:_ctl3:_ctl0
_ctl0:_ctl4:_ctl0
_ctl0:_ctl5:_ctl0
_ctl0:_ctl6:_ctl0
_ctl0:_ctl7:_ctl0and if you check the HTML source code, you will see they are exactly the names for those <input type=checkbox ..>Now, come back to the original question, what if you set DataGrid1.AllowPaging = True, and reduce the number of DataRows to 2? When the DataGrid is bound, everytime a row/cell is added to the control hierarchy, there are some catchupes to do, including invoking the Init/LoadViewState/ProcessPostData/Load event handler/method for the newly added control. So when you check the first checkbox, the check state will be restored along the way.When the Pager row is created/added, the system will know the third row (the Pager) is no longer valid according to the above ViewState, thus throws an exception. If you don't have DataGrid1.AllowPaging = True or have DataGrid1.AllowPaging = FALSE, the third row is never created/added and it will never check if the data is valid or not. Another way to verify is to create a FooterTemplate for DataGridTemplate and set ShowFooter= true, you will see the exact same errorsHow do you fix the problem? I wish you can clear the postdata stuffs, but I cannot find any such method, for now, you can do the following to cheat ASP.NET, :-)DataGrid1 = New DataGrid()
DataGrid1.ID = "DataGrid1" + DateTime.Now.ToString()
DataGrid1.AllowPaging = True
==>
'DataGrid1.AllowPaging = Truethen check the first checkbox, then click on Submit button, you can see that the first checkbox is still checked even if you rebind the whole thing!That means, even if you set the DataGrid's EnableViewState to false, the system still records these checkboxes' ViewState. If you don't believe me, open the HTML source in IE, and copy the value of the hidden control __VIEWSTATE to this page and click on "Parse ViewState" button, http://www.wilsondotnet.com/Demos/ViewState.aspxyou will see something like-1360000050
null
ArrayList
_ctl0:_ctl3:_ctl0
_ctl0:_ctl4:_ctl0
_ctl0:_ctl5:_ctl0
_ctl0:_ctl6:_ctl0
_ctl0:_ctl7:_ctl0and if you check the HTML source code, you will see they are exactly the names for those <input type=checkbox ..>Now, come back to the original question, what if you set DataGrid1.AllowPaging = True, and reduce the number of DataRows to 2? When the DataGrid is bound, everytime a row/cell is added to the control hierarchy, there are some catchupes to do, including invoking the Init/LoadViewState/ProcessPostData/Load event handler/method for the newly added control. So when you check the first checkbox, the check state will be restored along the way.When the Pager row is created/added, the system will know the third row (the Pager) is no longer valid according to the above ViewState, thus throws an exception. If you don't have DataGrid1.AllowPaging = True or have DataGrid1.AllowPaging = FALSE, the third row is never created/added and it will never check if the data is valid or not. Another way to verify is to create a FooterTemplate for DataGridTemplate and set ShowFooter= true, you will see the exact same errorsHow do you fix the problem? I wish you can clear the postdata stuffs, but I cannot find any such method, for now, you can do the following to cheat ASP.NET, :-)DataGrid1 = New DataGrid()
DataGrid1.ID = "DataGrid1" + DateTime.Now.ToString()