动态用户控件数据丢失中的动态 select 元素
Dynamic select element in dynamic user control data loss
经过几天的搜索论坛、阅读文档和与队友会面后,我还没有找到解决这个问题的方法。
我在 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 行长。写出来并不好玩。但是,我这样做的原因是用它在后面的代码中创建 <select>
标签,并在前端将其分配给 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
当在动态下拉列表中选择一个值时,任何回发都会清除该选择。任何关于为什么会发生这种情况以及我可以做些什么来解决这个问题的任何见解都将不胜感激。
两天没有答案,总共有 27 次浏览,我怀疑我是否会很快得到这个问题的答案。因此,我将与正在寻找我昨晚提出的这个问题的解决方案的任何人分享。
我意识到选项组只不过是一个带有 header 的列表,对吧?什么是 header but some text that is just for display, and some text that is just for display when it comes input?已禁用!
有了这个,我决定稍微改变我的代码并使用 asp DropDownList 为每个 header 显示一个禁用字段,而不是尝试创建动态 select 在后面的代码中,前面提到了数据丢失问题并保护了视图状态。
我的数据结构保持不变。
data.xml
<account>
<group>Group 1</group>
<value>Value 1</value>
</account>
我的表单方法保持不变,我将保留上面的那些,不再将它们复制到这里。
变化就在这里。
在我的控制下,前端改的很简单;将 <div>
替换为 <asp:DropDownList>
.
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
这个新代码生成一个包含 headers 组的 DropDownList!它没有 粗体 和 斜体 header,而是禁用了 header。您可以随时通过 CSS select 或您想要的样式找到它!
我希望仍在寻找此问题的超级简单解决方案的任何人都会遇到这个问题并发现它有帮助。
经过几天的搜索论坛、阅读文档和与队友会面后,我还没有找到解决这个问题的方法。
我在 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 行长。写出来并不好玩。但是,我这样做的原因是用它在后面的代码中创建 <select>
标签,并在前端将其分配给 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
当在动态下拉列表中选择一个值时,任何回发都会清除该选择。任何关于为什么会发生这种情况以及我可以做些什么来解决这个问题的任何见解都将不胜感激。
两天没有答案,总共有 27 次浏览,我怀疑我是否会很快得到这个问题的答案。因此,我将与正在寻找我昨晚提出的这个问题的解决方案的任何人分享。
我意识到选项组只不过是一个带有 header 的列表,对吧?什么是 header but some text that is just for display, and some text that is just for display when it comes input?已禁用!
有了这个,我决定稍微改变我的代码并使用 asp DropDownList 为每个 header 显示一个禁用字段,而不是尝试创建动态 select 在后面的代码中,前面提到了数据丢失问题并保护了视图状态。
我的数据结构保持不变。
data.xml
<account>
<group>Group 1</group>
<value>Value 1</value>
</account>
我的表单方法保持不变,我将保留上面的那些,不再将它们复制到这里。
变化就在这里。
在我的控制下,前端改的很简单;将 <div>
替换为 <asp:DropDownList>
.
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
这个新代码生成一个包含 headers 组的 DropDownList!它没有 粗体 和 斜体 header,而是禁用了 header。您可以随时通过 CSS select 或您想要的样式找到它!
我希望仍在寻找此问题的超级简单解决方案的任何人都会遇到这个问题并发现它有帮助。