为了比标题更有描述性,我在www.example.com中有一系列下拉列表asp.net,它们都填充了来自同一过程的相同值。我试图找出一种方法来删除值从后续的下拉列表中,如果该值已经被选中在以前的列表。例如,如果用户在“ddl 1”中选择“Value 1”,则“Value 1”不应出现在“ddl 2”或任何其他后续列表(ddl 3,ddl 4等...)中。
下拉列表:
<td>
<asp:DropDownList ID="ddlEquipmentType1" runat="server" AppendDataBoundItems="true" AutoPostBack="true" Width="200px" />
<asp:TextBox runat="server" name="txtIndoorUnit1SerialNumber" Placeholder="Serial #" MaxLength="20" ID="txtIndoorUnit1SerialNumber" Style="width: 200px;" errorName="<%$ Resources:Locale, Global_IndoorUnit1SerialNumber%>" />
<span runat="server" id="vldReqIndoorUnit1SerialNumber" style="color: Red;" Visible="False">*</span>
</td>
</tr>
<tr id="trIndoorUnit2SerialNumber" runat="server" visible="false">
<td style="vertical-align:top">
<asp:label runat="server" id="Label30" Text="<%$ Resources:Locale, Global_IndoorUnit2SerialNumber%>" />
</td>
<td>
<asp:DropDownList ID="ddlEquipmentType2" runat="server" AppendDataBoundItems="true" AutoPostBack="true" Width="200px" />
<asp:TextBox runat="server" name="txtIndoorUnit2SerialNumber" Placeholder="Serial #" MaxLength="20" ID="txtIndoorUnit2SerialNumber" Style="width: 200px;" errorName="<%$ Resources:Locale, Global_IndoorUnit2SerialNumber%>" />
<span runat="server" id="vldReqIndoorUnit2SerialNumber" style="color: Red;" Visible="False">*</span>
</td>
</tr>
(还有更多,但这是他们都是如何设置的)
填充程序:
Protected Sub PopEquipmentDDLs()
Dim dt As DataTable = New DataTable
Dim strSQL As String = "SELECT RecID, EquipmentType FROM EquipmentTypes WHERE RecID IN (SELECT PrimaryEType FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType1 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType2 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType3 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType4 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType5 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType6 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType7 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType8 FROM ETRelationship WHERE RecID = @RecID UNION ALL SELECT AccessoryEType9 FROM ETRelationship WHERE RecID = @RecID) AND EquipmentType <> @PEquipmentType"
Dim ddlCollection As New List(Of DropDownList)() From {ddlEquipmentType1, ddlEquipmentType2, ddlEquipmentType3, ddlEquipmentType4, ddlEquipmentType5, ddlEquipmentType6, ddlEquipmentType7, ddlEquipmentType8, ddlEquipmentType9}
Dim selectedValues As New Dictionary(Of Integer, String)()
'For i As Integer = 0 To ddlCollection.Count - 1
' Dim ddl As DropDownList = ddlCollection(i)
' If ddl.SelectedIndex > 0 Then
' selectedValues.Add(i, ddl.SelectedItem.Value)
' End If
'Next
Using conn As New SqlConnection(ConfigurationManager.ConnectionStrings("WillisConnectionString").ToString)
Using cmdSQL As New SqlCommand(strSQL, conn)
cmdSQL.Parameters.Add("RecID", SqlDbType.Int).Value = ddlNbZones.SelectedValue
cmdSQL.Parameters.Add("PEquipmentType", SqlDbType.VarChar).Value = txtEType.Text
conn.Open()
dt.Load(cmdSQL.ExecuteReader())
'Clear all drop-down lists
For Each ddl As DropDownList In ddlCollection
ddl.Items.Clear()
ddl.Items.Add(New ListItem("---SELECT EQUIPMENT---", "0"))
Next
'populate drop-downs
For i As Integer = 0 To ddlCollection.Count - 1
Dim ddl As DropDownList = ddlCollection(i)
ddl.DataSource = dt
ddl.DataTextField = "EquipmentType"
ddl.DataValueField = "RecID"
ddl.DataBind()
'If selectedValues.ContainsKey(i) Then
' ddl.SelectedValue = selectedValues(i)
'End If
Next
For Each item In ddlEquipmentType2.Items
System.Diagnostics.Debug.WriteLine(item)
Next
End Using
End Using
End Sub
过滤程序:
Private Sub FilterDDLs(ByVal ddlCollection As List(Of DropDownList))
For i As Integer = 0 To ddlCollection.Count - 2
Dim ddl As DropDownList = ddlCollection(i)
' Skip filtering if selected index is 0
If ddl.SelectedIndex > 0 Then
Dim selectedItemText As String = ddl.SelectedItem.Text
For j As Integer = i + 1 To ddlCollection.Count - 1
Dim subsequentDDL As DropDownList = ddlCollection(j)
Dim itemToRemove As ListItem = subsequentDDL.Items.FindByText(selectedItemText)
If itemToRemove IsNot Nothing Then
subsequentDDL.Items.Remove(itemToRemove)
End If
Next
End If
Next
End Sub
我从下拉列表的databinding事件调用过滤器过程,它循环通过所有列表并尝试根据匹配的文本删除项目,我也尝试根据选定的值删除它们,因为它们都是相同的值。
如果我删除“If ddl.SelectedIndex > 0 Then”,并且不查找索引大于0的ddl,它将删除我在填充过程中添加的值(0)处的ListItem,但无论出于什么原因,我无法让它删除值1+。
我不确定我是否在错误的地方调用了这个函数,但是我尝试在“selectedIndexChanged”事件中调用过滤器过程也没有用。
我还尝试在填充过程中过滤列表,然后在每个“selectedIndexChanged”事件中调用pop过程,而不是为它设置一个单独的过程。因此,注解代码将选定的值存储在字典中,然后在事后重新分配它们。
任何有关此问题的帮助将不胜感激。
1条答案
按热度按时间gk7wooem1#
好吧,那么说这个标记:
我将使用一个列表框,但列表框的“事件”模型与组合框(下拉列表)100%相同,并且此代码可以与列表框或DropDownList互换。
因此,标记:
让我们在页面上删除3个列表框。
例如:
要加载的代码:
级联码-我们只需要lb 1和lb 2。
因此,这段代码:
我们现在看到/得到这个:
当然,现在我使用了一个helper例程来加载sql(只返回一个数据表)。这是从我的全球handy花花公子助手例程。(并且对于上面的代码示例并不重要,但是我在这里仅供参考
编辑:对于怀疑论者,以上为下拉列表。
因此,采用现有的标记,更改为下拉列表
所以,codebeath现在变成了这样:
现在我们看到/得到这个:
当然,这回避了一个问题,为什么不使用一个列表框与selectmode=“multiple”。
列表框唯一真实的的缺点是,用户通常不知道您可以按住CTRL键来选择多个项目,因此,这确实需要键盘+鼠标操作。