0

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

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

这种动态生成的表单的目标有两个:

  1. 在现有网站上创建/修改/删除新闻帖子的能力
  2. 以尽可能少的代码更改重用此代码的能力

这是我当前的代码:

<%@ 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>

谢谢!

4

1 回答 1

0

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

我建议更仔细地研究一些内置控件,例如FormViewand DetailsView。如果没有记忆,他们可以为结果集中的列自动生成输入控件。如果您需要微调它们的操作方式(例如,通过排除主键字段),您可以对控件进行子类化并更改其对要呈现的列的选择。

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

于 2013-03-17T00:40:36.300 回答