DataGrid动态生成问题,晕死了,高手帮帮忙~~~~~~~~~~~~~~~~

Endlessrain 2003-07-22 06:51:58
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
Dim col1 As New TemplateColumn()
col1.ItemTemplate = New DataGridTemplate(ListItemType.Item, "CheckBox")
DataGrid1.Columns.Add(col1)
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") = "数据1"
dt.Rows.Add(row)
row = dt.NewRow()
row.Item("a") = "数据2"
dt.Rows.Add(row)

If Not Page.IsPostBack Then
row = dt.NewRow()
row.Item("a") = "数据3"
dt.Rows.Add(row)
row = dt.NewRow()
row.Item("a") = "数据4"
dt.Rows.Add(row)
row = dt.NewRow()
End If
DataGrid1.DataSource = dt
DataGrid1.DataBind()
End Sub

w我想动态生成DataGrid ,DataGrid中包括一列CheckBox的模版列,第一次加载页面时能够正常显示,但是如果我在postback时,把数据源的记录条数减少(就向我写的代码一样),就会报如下错误:

指定的转换无效。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.InvalidCastException: 指定的转换无效。

源错误:

执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。

堆栈跟踪:


[InvalidCastException: 指定的转换无效。]
System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad)
System.Web.UI.Page.ProcessRequestMain()


如果我不加入动态的CheckBox模版列,或者把DataGrid的AllowPaging 属性置为False,就不会有错,请问这是为什么,这个问题搞了一天了,大家帮帮忙啊~~~~~~~

...全文
41 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Endlessrain 2003-07-23
  • 打赏
  • 举报
回复
感谢思归,你所说的差不多我都明白了,用你的方法我也试成功了,我把Checkbox换成checkboxlist也行了,再次感谢你!
saucer 2003-07-23
  • 打赏
  • 举报
回复
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 = True

then 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.aspx

you will see something like

-1360000050
null
ArrayList
_ctl0:_ctl3:_ctl0
_ctl0:_ctl4:_ctl0
_ctl0:_ctl5:_ctl0
_ctl0:_ctl6:_ctl0
_ctl0:_ctl7:_ctl0

and 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 errors

How 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()


saucer 2003-07-23
  • 打赏
  • 举报
回复
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 = True

then 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.aspx

you will see something like

-1360000050
null
ArrayList
_ctl0:_ctl3:_ctl0
_ctl0:_ctl4:_ctl0
_ctl0:_ctl5:_ctl0
_ctl0:_ctl6:_ctl0
_ctl0:_ctl7:_ctl0

and 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 errors

How 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()


cjc19281 2003-07-23
  • 打赏
  • 举报
回复
我参与的问题
feirulin 2003-07-23
  • 打赏
  • 举报
回复
晕了
wolve 2003-07-23
  • 打赏
  • 举报
回复
没时间看这么多代码,你最好说一下思路
Endlessrain 2003-07-23
  • 打赏
  • 举报
回复
我在这里加只是为了调试数据的方便,其实我要表达的是第二次的数据比第一次的数据少
goody9807 2003-07-23
  • 打赏
  • 举报
回复
If Not Page.IsPostBack Then ..最好不用在函数里,应当用在page_load中
tianjin99 2003-07-23
  • 打赏
  • 举报
回复
我也遇到了同样的问题,各位高手帮帮忙
Endlessrain 2003-07-23
  • 打赏
  • 举报
回复
思归大侠,帮忙啊~~~~~~~~~~~~~
Endlessrain 2003-07-23
  • 打赏
  • 举报
回复
源代码如下:
这是页面的基类:
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 Class

End Class

然后随便找个界面,继承class1,就行了
saucer 2003-07-22
  • 打赏
  • 举报
回复
I cannot reproduce your problem, please post all the relevant code
xrll 2003-07-22
  • 打赏
  • 举报
回复
If Not Page.IsPostBack Then
位置好象有问题!
kevincsg 2003-07-22
  • 打赏
  • 举报
回复
:(

62,052

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧