创建表单控件的变量表行

时间:2018-03-22 16:16:33

标签: asp.net vb.net gridview dataset

来自主要的PHP和Javascript背景,我习惯于创建直接处理HTML编写的低级函数,或者使用像React这样的声明性库,它允许您根据数据声明HTML的结构,然后用数据填写。

现在我正在使用ASP.NET,我正在尝试更多地使用“.NET方式”,而不是仅仅遵循我在其他框架中使用的相同模式。

目的:

默认情况下,创建一个包含10行的表。这些行中的每一行都包含用户将学生数据输入的文本框。如果他们认为合适,他们可以添加更多行。此数据与数据库或其他任何内容无关,它只用于填充电子邮件。

我的第一次尝试:

最初我尝试创建一个DataSet,其定义的模式与输入的匹配。

studentData = New DataSet()
studentData.Tables.Add()

studentData.Tables(0).Columns.Add("StudentID")
studentData.Tables(0).Columns.Add("StudentName")
studentData.Tables(0).Columns.Add("StudentGrade")
studentData.Tables(0).Columns.Add("ContactPhone")

在Init上我会向表单添加10行,并将数据绑定到GridView

For index As Integer = 1 To ViewState("StudentCount")
    tblStudents.Rows.Add(GetTableRow(index))
Next

grdStudents.DataSource = studentData
grdStudents.DataBind()

GridView的声明如下:

<asp:GridView ID="grdStudents" runat="server" AutoGenerateColumns="false">
        <Columns>
            <asp:TemplateField HeaderText="Student Id#">
                <ItemTemplate>
                    <asp:TextBox runat="server" ID="studentId" Value='<%# Eval("StudentId") %>'></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Last/First Name">
                <ItemTemplate>
                    <asp:TextBox runat="server" ID="studentName" Value='<%# Eval("StudentName") %>'></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Grade">
                <ItemTemplate>
                    <asp:TextBox runat="server" ID="studentGrade" Value='<%# Eval("StudentGrade") %>'></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Phone #">
                <ItemTemplate>
                    <asp:TextBox runat="server" ID="phone" Value='<%# Eval("ContactPhone") %>'></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

问题

所以这给了我一个我想要的形式,这是一种很好的陈述方式,这就是我想要的。但是,尽管我尝试了不同的东西,但数据永远不会持久存在于DataSet中。我尝试在会话中存储DataSet,但无济于事。我将Eval更改为Bind,但无效。

当我在没有回发时只调用TextBox时,grdStudents.DataBind()中的数据仍然存在,但这对我来说没有太大作用;我想让数据重新进入DataSet。我明白为什么会发生这样的事情:如果数据永远不会回到DataSet中,调用DataBind将始终将控件绑定到空数据。

我在网上研究的几乎所有关于DataSet和更新它们的内容总是提到它们有一个支持数据库来更新。我没有数据库,这只是我想要生成的本地表单。也许我正在吠叫错误的树,所以我改变了方法。

我目前的解决方案:

我目前的解决方案只是手动创建所有内容。

我从ASP开始使用基表结构:

<asp:Table runat="server"ID="tblStudents" ClientIDMode="Static">
            <asp:TableHeaderRow CssClass="text-center">
                <asp:TableHeaderCell Width="10%">Student Id #</asp:TableHeaderCell>
                <asp:TableHeaderCell Width="20%">Last/First Name</asp:TableHeaderCell>
                <asp:TableHeaderCell Width="5%">Grade</asp:TableHeaderCell>
                <asp:TableHeaderCell Width="15%">Phone #</asp:TableHeaderCell>
            </asp:TableHeaderRow>
        </asp:Table>

我只是手动创建控件

' GetCellForControl is a little helper function which just puts a control in a cell and gives you the cell
Protected Function CreateTableRow(ByVal index As Integer)
            Dim row As TableRow = New TableRow

            row.Cells.Add(GetCellForControl(New TextBox With {.ID = "StudentId_" & index,  .MaxLength = 10}))
            row.Cells.Add(GetCellForControl(New TextBox With {.ID = "StudentName_" & index }))
            row.Cells.Add(GetCellForControl(New TextBox With {.ID = "StudentGrade_" & index, .MaxLength = 3}))
            row.Cells.Add(GetCellForControl(New TextBox With {.ID = "Phone_" & index, .TextMode = TextBoxMode.Phone}))

            Return row
        End Function

'In Page_Load
 For index As Integer = 1 To ViewState("StudentCount")
            tblStudents.Rows.Add(CreateTableRow(index))
        Next

所以这很好用。要检索数据,我可以遍历每个TableRow并从每个TableCell中拉出控件,或者我可以使用每个控件的可预测ID来提取数据。

“问题”

这种方法正确地发挥作用,因此没有真正的问题,但我觉得我错过了一些东西。我是ASP和.NET编程的新手,所以我知道我还不知道有很多功能。所以我希望深入了解能够以更惯用的方式解决这个问题的功能。

到目前为止,我已经使用将GridView绑定到DataSet的声明式样式创建了其他表单,但其中大多数都涉及DataSet的后备数据库。在这种情况下,它只是一系列相同的行输入,可能发生在10到n次之间。看起来很简单吧?我目前的解决方案很简单。但对我来说,这只是硬编码10行和输入的下一步,必须有更好的东西!

我觉得我的第一次尝试是接近我想要的东西,但我不知道究竟需要什么来点击所有内容。

有没有办法在ASP.NET中使用声明式方法来实现目标?

TL; DR :我对ASP.NET感到厌烦,我试图通过理解以.NET方式解决问题的惯用方法而不是从其他框架来逐渐减少吸引力习惯或天真的必要方式。

1 个答案:

答案 0 :(得分:1)

This article might help。他最终使用了一个数据库,但您可以使用他的一些代码将网格数据简单地保存到数据表中,然后根据需要使用它。

顺便说一句,数据集包含用于检索,更新和删除数据库的内置方法,因此如果您不使用数据库,则不需要数据集;数据表应该足够了。第h