【问题标题】:Dynamic select element in dynamic user control data loss动态用户控制数据丢失中的动态选择元素
【发布时间】:2018-12-17 11:24:24
【问题描述】:

在搜索论坛、阅读文档和与队友会面几天后,我还没有找到解决此问题的方法。

我在 VB.NET 项目中有一个表单,它通过单击 asp 按钮动态添加用户控件和回发。之所以有回发,是因为用户控件和主页面之间发生了计算。

有一个下拉列表需要有<optgroup> 标记。为此,我将数据列表写入 XML 文件,其结构如下:

<AccountListData>
    <account>
        <group>OPTION GROUP NAME HERE</group>
        <value>OPTION VALUE/TEXT HERE</value>
    </account>
    <account>...</account>
</AccountListData>

XML 文件有 1117 行长。写出来一点都不好玩。但是,我这样做的原因是使用它在后面的代码中创建&lt;select&gt; 标记并将其分配给前端div 标记的innerHTML 属性。它看起来像这样:

Form.aspx

    <table>
      <tr>
        <td id="DateLabel" runat="server">Date:</td>
        <td id="DescriptionLabel" runat="server">Description:</td>
        <td id="AmountLabel" runat="server">Amount:</td>
        <td id="DropDownLabel" runat="server">Select:</td>
      </tr>
      <asp:Placeholder ID="ph1" runat="server"></asp:Placeholder>
    </table>
    <asp:Button ID="AddItemButton" runat="server" CausesValidation="false" Text="Add Item">
    <asp:Label ID="RowCountLabel" runat="server"></asp:Label>

Form.aspx.vb

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
      'Add/Removed User Control
      AddRemoveUserControl()
      ScriptManager.RegisterStartupScript(Me, Me.[GetType](), "CalculateCosts", "Javascript function();"), True)
    End Sub
    ...
    Public Function GetPostbackControlName(ByVal Page As Page) As String
      Dim ctrlName As String
      ctrlName = Page.Request.Params.Get("__EVENTTARGET")
      Return ctrlName
    End Function
    ...
    Private Sub AddRemoveUserControl()
      'Get and check the ID of what caused the postback
      Dim c As Control = GetPostbackControlName(Page)

      If Not IsNothing(c) Then
        If c.ID.ToString = "AddItemButton" Then
          RowCountLabel.Text = CInt(RowCountLabel.Text) + 1
        End If
      End If

      'Get ID for dynamic user controls
      Dim ControlID As Integer = 0
      For i As Integer = 1 To (CInt(RowCountLabel) - 1)
        Dim DynamicControl As ItemTable = LoadControl("usercontrols/ItemTable.ascx")
        DynamicUserControl.ID = "uc" & CStr(ControlID)

        'Add an event handler for the usercontrol
        AddHandler DynamicUserControl.RemoveUserControl, AddressOf Me.HandleRemoveUserControl

        'Add user control to placeholder on front end
        ph1.Controls.Add(DynamicUserControl)

        'Number the amount of user controls
        ControlID += 1
      Next
      NumberItemTable()
    End Sub
    ...
    Private Sub HandleRemoveUserControl(sender As Object, e As EventArgs)
      'Removes usercontrol from placeholder and lowers count #
    End Sub
    ...
    Private Sub NumberItemTable()
      'Gives a number value to a property in the usercontrol
    End Sub

Control.ascx

    <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ItemTable.ascx.vb" Inherits=".ItemTable" %>
<tr>
  <td>
    <asp:Textbox ID="Date" runat="server" CssClass="datepicker"></asp:Textbox></td>
  <td>
    <asp:Textbox ID="Description" runat="server"></asp:Textbox></td>
  <td>
    <asp:Textbox ID="Amount" runat="server"></asp:Textbox></td>
  <td>
    <div ID="DynamicSelect" runat="server"></div></td>
</tr>

Control.ascx.vb

Dim XMLInfo As XDocument

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
  FillDropDownList()
End Sub

Private Sub FillDrowDownList()
  'Get XML data
  Dim XMLData 'all the XML data is loaded as an XDocument here
  Dim temp As string
  'WHERE THE DROPDOWN IS DYNAMICALLY CREATED WITH XML DATA
  DynamicSelect.InnerHTML += "<select ID='" + Me.ID.ToString + "CreatedSelect'><option value='' selected disabled>- Select -</option>"
  For Each element As XElement In XMLData.Descendants("account")
    Dim group As String = element.<group>.Value.ToString
    Dim value As String = element.<value>.Value.ToString

    If group <> "" Then
      If group <> temp Then
        temp = group
        DynamicSelect.InnerHTML += "</optgroup>"
        DynamicSelect.InnerHTML += "<optgroup label='" + group + "'>"
      End If
    End If
    DynamicSelect.InnerHTML += "<option value='" + value + "'>" + value + "</option>"
  Next
  DynamicSelect.InnerHTML += "</select>"
End Sub

当在动态下拉列表中选择一个值时,任何回发都会清除该选择。任何关于为什么会发生这种情况以及我可以做些什么来解决这个问题的见解将不胜感激。

【问题讨论】:

    标签: asp.net vb.net user-controls html-select dynamic-usercontrols


    【解决方案1】:

    两天没有答案,总共有 27 次观看,我怀疑我很快就会得到这个问题的答案。所以,我将与你们中的任何人分享我昨晚提出的这个问题的解决方案。

    我意识到选项组只不过是一个带有标题的列表,对吧?什么是标题,但只是一些仅用于显示的文本,以及在输入时仅用于显示的一些文本是什么?已停用!

    有了这个,我决定稍微改变我的代码并使用 asp DropDownList 为每个标题显示一个禁用字段,而不是尝试在后面的代码中创建动态选择,从而解决数据丢失问题并保护视图状态的状态。

    我的数据结构保持不变。

    数据.xml

    <account>
      <group>Group 1</group>
      <value>Value 1</value>
    </account>
    

    我的表单方法保持不变,我将保留上面的内容,不再将它们复制到这里。

    这就是变化所在。

    在我的控制下,前端改的很简单;将&lt;div&gt; 替换为&lt;asp:DropDownList&gt;

    Control.ascx

    <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ItemTable.ascx.vb" Inherits=".ItemTable" %>
    <tr>
      <td>
        <asp:Textbox ID="Date" runat="server" CssClass="datepicker"></asp:Textbox></td>
      <td>
        <asp:Textbox ID="Description" runat="server"></asp:Textbox></td>
      <td>
        <asp:Textbox ID="Amount" runat="server"></asp:Textbox></td>
      <td>
        <div ID="DynamicSelect" runat="server"></div></td>
    </tr>
    

    我后面的控制代码改为:

    Control.ascx.vb

    Imports System.Web.UI.WebControls
    

    ...

    Private Sub FillDrowDownList()
    'Get XML data
    Dim XMLData 'all the XML data is loaded as an XDocument here
    Dim temp As string = ""
    Dim i As Integer = 0
    'Check if the control already has the dropdown
    If DynamicSelect.Items.Count < 1 Then
      DynamicSelect.Items.Add(New ListItem("- Select -", ""))
      DynamicSelect.Items(i).Attributes.Add("selected", "true")
      DynamicSelect.Items(i).Attributes.Add("disabled", "true")
      i += 1
      'loop through XML data
      For Each element As XElement In XMLData.Descendants("account")
        Dim group As String = element.<group>.Value.ToString
        Dim value As String = element.<value>.Value.ToString
    
        If temp <> group Then
          temp = group
          DynamicSelect.Items.Add(New ListItem(group, ""))
          DynamicSelect.Items(i).Attributes.Add("disabled", "true")
          i += 1
        End If
    
        DynamicSelect.Items.Add(New ListItem(value, value))
    
        i += 1
      End If
    End Sub
    

    这个新代码生成一个带有组头的 DropDownList!它没有 bolditalic 标头,只有一个禁用的标头。您可以随时根据自己的喜好使用 CSS 选择器和样式来寻找!

    我希望任何仍在寻找这个问题的超级简单解决方案的人都会遇到这个问题并觉得它很有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 2023-04-09
      • 1970-01-01
      • 2016-01-14
      相关资源
      最近更新 更多