ASP.NET GridView编程添加行后TextBox内容不显示问题求助
问题原因及解决方案
一、初始添加行时TemplateField的TextBox为空的原因
你定义的TemplateField中的TextBox未与DataTable字段绑定,而BoundField通过DataField属性直接关联数据源字段,所以能正常渲染内容;TemplateField需要显式指定TextBox的Text属性绑定到对应字段,才能将数据源的值显示到输入框中。
二、添加多行时第一行TextBox内容丢失的核心问题
- 重复创建DataTable列:在
ElseIf grdNewClaim.Rows.Count > 0分支中,每次点击添加按钮都会执行dtGrd.Columns.Add()重复创建列,导致DataTable结构混乱,数据绑定逻辑异常。 - 错误读取TemplateField内容:通过
grdNewClaim.Rows(i).Cells(5).Text获取TemplateField中TextBox的内容是错误的——GridView单元格的Text属性仅对应BoundField的内容,TemplateField内的控件必须通过FindControl方法获取其实际输入值。 - 未持久化数据源状态:
dtGrd作为页面级变量,在ASP.NET回发时会被重新初始化,之前存储的数据会丢失,需要将其存入ViewState中保留状态。
修正后的关键代码示例
1. 修改前端TemplateField,添加数据绑定
<asp:GridView ID="grdNewClaim" CssClass="table table-bordered table-condensed" GridLines="None" runat="server" AutoGenerateColumns="false"> <Columns> <asp:BoundField DataField="claim_type" HeaderText="Claim Type" /> <asp:BoundField DataField="purpose_desc" HeaderText="Purpos/Description" /> <asp:BoundField DataField="currency" HeaderText="Currency" /> <asp:BoundField DataField="amount" HeaderText="Amount" /> <asp:TemplateField HeaderText="Currency Rate"> <ItemTemplate> <asp:TextBox ID="txtChangeCurrRate" runat="server" Text='<%# Eval("CurrencyRate") %>'></asp:TextBox> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Converted Rate"> <ItemTemplate> <asp:TextBox ID="txtChangeConvertedRate" runat="server" Text='<%# Eval("ConvertedRate") %>'></asp:TextBox> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
2. 修正后端代码,持久化数据源并正确读取控件值
' 通过ViewState持久化数据源,避免回发丢失 Private Property dtGrd As DataTable Get If ViewState("dtGrd") Is Nothing Then Dim dt As New DataTable dt.Columns.Add("claim_type") dt.Columns.Add("purpose_desc") dt.Columns.Add("currency") dt.Columns.Add("amount") dt.Columns.Add("CurrencyRate") dt.Columns.Add("ConvertedRate") ViewState("dtGrd") = dt End If Return DirectCast(ViewState("dtGrd"), DataTable) End Get Set(value As DataTable) ViewState("dtGrd") = value End Set End Property Private Sub LoadGrid() grdNewClaim.DataSource = dtGrd grdNewClaim.DataBind() End Sub Private Sub addClaimProgrammatically() ' 先更新已有行的TemplateField控件值到数据源 If grdNewClaim.Rows.Count > 0 Then For i = 0 To grdNewClaim.Rows.Count - 1 Dim txtCurrRate As TextBox = DirectCast(grdNewClaim.Rows(i).FindControl("txtChangeCurrRate"), TextBox) Dim txtConvertedRate As TextBox = DirectCast(grdNewClaim.Rows(i).FindControl("txtChangeConvertedRate"), TextBox) dtGrd.Rows(i)("CurrencyRate") = txtCurrRate.Text dtGrd.Rows(i)("ConvertedRate") = txtConvertedRate.Text Next End If ' 添加新行 Dim dr As DataRow = dtGrd.NewRow dr.Item("claim_type") = cmbClaimtype.Text dr.Item("purpose_desc") = txtPurpDesc.Text dr.Item("currency") = cmbCurrency.Value dr.Item("amount") = txtAmmount.Text dr.Item("CurrencyRate") = lblCurrencyrate.Text dr.Item("ConvertedRate") = lblconvertedRateMYR.Text dtGrd.Rows.Add(dr) LoadGrid() End Sub Protected Sub btnAddClaim_Click(sender As Object, e As EventArgs) Handles btnAddClaim.Click addClaimProgrammatically() End Sub
内容的提问来源于stack exchange,提问作者Una O Lian
相关产品推荐
相关产品推荐

