2013-03-16 47 views
0

我目前正在尝试将代码在运行时动态生成一组HTML表单控件,然后对这些控件进行数据绑定。从我读过的内容来看,你不能绑定像<input><textarea>等形式的控件,但是我能找到的所有信息都来自几年前。不知道现在是否可以用.net 4.5做到这一点。ASP.net/VB.net在运行时生成数据绑定表格

在任何情况下,我所要求的是最好的方法是完成我想要做的事情,无论是利用我已有的东西,还是从完全不同的方向进行。

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

  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> 

谢谢!

回答

0

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

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

虽然这是事实,他们可能不会完全适合你的目的,“稳定完美的90%,节省了工作量的50%”。它们代表了很多功能,您不必编写,测试或支持。

+0

谢谢你的洞察Ann!现在我知道我想让自己做什么样的工作,我可能会使用FormView来实现这一点。另外,我真的很喜欢这句话......“完美的完美度达到了90%,节省了50%的努力。”我会记得那一个。 – TACHEON 2013-03-17 19:09:59