ASP.net/VB.net在运行时生成数据绑定表单

时间:2013-03-16 20:23:44

标签: asp.net vb.net data-binding sqldatasource

我目前正在尝试将在运行时动态生成一组HTML表单控件的代码放在一起,然后对这些控件进行数据绑定。从我读过的内容来看,你无法对像<input><textarea>等表单控件进行数据绑定,但是我能找到的所有信息都来自几年前。现在还不确定是否可以使用.net 4.5进行此操作。

无论如何,我要问的是,最好的方法是完成我正在尝试做的事情,无论是利用我已经拥有的,还是从完全不同的方向进行。

这种动态生成的表单的目标是双重的:

  1. 在现有网站上创建/修改/删除新闻帖子的能力
  2. 使用尽可能少的代码更改重用此代码的能力
  3. 这是我目前的代码:

    <%@ Import Namespace="System.Data" %> 
    <%@ Page Language="VB" %>
    
    <script runat="server">
        Protected Sub Page_Load(sender As Object, e As EventArgs)    
        Dim dataSourceInfo As New DataSourceInfo
        dataSourceInfo.TableName = "Post_Table"
        dataSourceInfo.DataColumns = {"PostTitle", "PostContent", "PostURL", "PublishDate", "ExpirationDate", "Active"}
        dataSourceInfo.KeyColumn = "ID"
    
        BuildCMSForm(dataSourceInfo)
        BindCMSForm(dataSourceInfo)
        End Sub
    
        Public Structure DataSourceInfo
        Dim TableName As String
        Dim DataColumns() As String
        Dim KeyColumn As String
        End Structure
    
        Public Sub BuildCMSForm(ByVal dataSourceInfo As DataSourceInfo)
        Dim dataSource As SqlDataSource = New SqlDataSource()
        Dim strSelectCommand As String
        dataSource.ProviderName = "System.Data.SqlClient"
        dataSource.ConnectionString = "Data Source=LOCALHOST\SQLEXPRESS;Initial Catalog=Test_Web;Integrated Security=SSPI"
        strSelectCommand = "SELECT COLUMN_NAME, DATA_TYPE " & _
            "FROM INFORMATION_SCHEMA.COLUMNS " & _
            "WHERE TABLE_NAME = '" & dataSourceInfo.TableName & "' " & _
            "AND COLUMN_NAME IN ("
    
        For Each col As String In dataSourceInfo.DataColumns
            strSelectCommand = strSelectCommand & "'" & col.ToString & "', "
        Next
    
        strSelectCommand = strSelectCommand.Substring(0, strSelectCommand.Length - 2) & ")"
        dataSource.SelectCommand = strSelectCommand
    
        Dim dv As DataView
        dv = CType(dataSource.Select(DataSourceSelectArguments.Empty), DataView)
    
        For Each row As DataRow In dv.Table.Rows()
            Dim newControlDiv As HtmlGenericControl = New HtmlGenericControl("div")
            newControlDiv.Attributes.Add("id", "CMSControlDiv" & row.Item(0).ToString)
            newControlDiv.Attributes.Add("class", "CMSControlDiv")
            newControlDiv.InnerHtml = row.Item(0).ToString & ":<br />"
    
            Select Case row.Item(1).ToString
            Case "text"
                Dim newControl As TextBox = New TextBox
                newControl.TextMode = TextBoxMode.MultiLine
                newControl.ID = row.Item(0).ToString
                newControl.Attributes.Add("class", "CMSControl")
    
                newControlDiv.Controls.Add(newControl)
            Case "varchar"
                Dim newControl As TextBox = New TextBox
                newControl.ID = row.Item(0).ToString
                newControl.Attributes.Add("class", "CMSControl")
    
                newControlDiv.Controls.Add(newControl)
            Case "datetime"
                Dim newControl As TextBox = New TextBox
                newControl.ID = row.Item(0).ToString
                newControl.Attributes.Add("class", "CMSControl")
    
                newControlDiv.Controls.Add(newControl)
            Case "bit"
                Dim newControl As CheckBox = New CheckBox
                newControl.ID = row.Item(0).ToString
                newControl.Attributes.Add("class", "CMSControl")
    
                newControlDiv.Controls.Add(newControl)
            End Select
    
            AdminForm.Controls.Add(newControlDiv)
        Next
    
        Dim newSubmit As HtmlInputSubmit = New HtmlInputSubmit
        newSubmit.Attributes.Add("id", "CMSSubmit")
        newSubmit.Value = "Submit"
    
        AdminForm.Controls.Add(newSubmit)
        End Sub
    
        Public Sub BindCMSForm(ByVal dataSourceInfo As DataSourceInfo)
        Dim dataSource As SqlDataSource = New SqlDataSource()
        Dim strSelectCommand As String
        Dim strColumns As String = ""
        dataSource.ProviderName = "System.Data.SqlClient"
        dataSource.ConnectionString = "Data Source=LOCALHOST\SQLEXPRESS;Initial Catalog=Test_Web;Integrated Security=SSPI"
        strSelectCommand = "SELECT TOP 1 {0} FROM {1} WHERE [PostType] = 'Event'"
    
        For Each col As String In dataSourceInfo.DataColumns
            strColumns = strColumns & "[" & col.ToString & "], "
        Next
    
        strColumns = strColumns.Substring(0, strColumns.Length - 2)
        dataSource.SelectCommand = String.Format(strSelectCommand, strColumns, dataSourceInfo.TableName)
    
        Dim dv As DataView
        dv = CType(dataSource.Select(DataSourceSelectArguments.Empty), DataView)
    
        For Each col As DataColumn In dv.Table.Columns()
    
        Next
        End Sub
    </script>
    
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head id="Head1" runat="server">
        <meta charset="utf-8" />
        <title></title>
        <link href="~/styles/main.css" rel="stylesheet" />
        </head>
        <body>
        <div id="wrapper" runat="server">
            <div id="Content" class="Content" runat="server">
            <form id="AdminForm" runat="server">
            </form>
            </div>
        </div>
        </body>
    </html>
    

    谢谢!

1 个答案:

答案 0 :(得分:0)

这将是一项很多工作。为了捕获用户所做的更改,您将不得不在每次回发时重建控件集,并在视图状态或会话中保留大量元数据,以便在需要更新时知道哪个控件属于哪个数据库字段

我建议您更加努力地查看某些内置控件,例如FormViewDetailsView。如果内存服务,它们可以自动为结果集中的列生成输入控件。如果您需要微调它们的工作方式(例如,通过排除主键字段),您可以对控件进行子类化并更改其选择的列以进行渲染。

虽然它们可能不会完全适合您的目的,但“90%的完美度可以节省50%的努力”。它们代表了许多您不必编写,测试或支持的功能。