【问题标题】:ASP.net/VB.net Generating a data bound form at runtimeASP.net/VB.net 在运行时生成数据绑定表单
【发布时间】:2013-03-05 11:04:00
【问题描述】:

我目前正在尝试将在运行时动态生成一组 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>

谢谢!

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢安的洞察力!既然我知道自己想要从事什么样的工作,我可能会使用 FormView 来解决这个问题。另外,我真的很喜欢这句话……“满足于 90% 的完美可以节省 50% 的努力。”我会记住那个的。
    猜你喜欢
    • 2012-08-13
    • 2013-06-27
    • 2013-05-06
    • 2010-10-29
    • 1970-01-01
    • 2012-11-25
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多