删除或禁用在另一个列表中选择的ComboBox项目 [英] Removing or disable ComboBox item which is selected in another list

查看:288
本文介绍了删除或禁用在另一个列表中选择的ComboBox项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 WinForm 上有三个组合框,如下所示:

  ___________________________ 
组合框列表1:| _______________________ | ___ |
___________________________
组合框列表2:| _______________________ | ___ |
___________________________
组合框列表3:| _______________________ | ___ |

每个组合框在设计时都会有一个A B,C。



默认情况下,列表1是表单上唯一活动的列表,列表2和列表3将在其前导者被选择时变为活动状态。



我想做的是,iF用户选择选项C,我想选项C不再可用于列表2和3。 >

我知道这将涉及组合框的 .SelectedIndexChanged 事件,但不知道在哪里开始编码。 / p>

我在StackOverflow上找到了以下答案,我的情况不适用,因为我在设计时提供项目,而不是通过导入文件: vb.net更改组合框选项,取决于

这类似于Steve的回答,但使用 DataSource 。此外,实际上不需要启用 / 禁用每个CBO。当他们进行更改时,先前的选择将从源中过滤。任何重复的上一个更改都将撤销。



CBO1始终拥有完整列表,而其他则省略之前的选择。你不能结束重复的选择,因为重新选择#2与#3相同,更改#3的内容替换选择列表中的第一个。

 '主列表
私有选项列表作为新列表(字符串)
私人忽略作为布尔

'初始化某处:
OptList.AddRange(New String(){Red,Green,Blue,Violet,Orange})
'设置cbos
' up:
ignore = True
cb1.DataSource = OptList.ToArray
cb1.SelectedIndex = -1
cb2.DataSource = OptList.ToArray
cb2.SelectedIndex = 1
cb3.DataSource = OptList.ToArray
cb3.SelectedIndex = -1
ignore = False

全部启用,他们可以任何顺序选择。

  Private Sub cbo_SelectedIndexChanged As Object,e As EventArgs)_ 
Handles cb1.SelectedIndexChanged,cb2.SelectedIndexChanged
如果忽略则退出Sub

Dim cbo = TryCast(sender,ComboBox)
如果cbo IsNot Nothing AndAlso cbo is cb1 then
cb2.DataSource = GetFilteredList(New String(){cb1.Items(cb1.SelectedIndex)})
Else
cb3.DataSource = GetFilteredList
结束如果
结束Sub

私有函数GetFilteredList(items As String()(String As String() )As String()
返回OptList.Except(items).ToArray()
结束函数

由于cbo3仅限于在#1或#2(一个从属)中没有选择的项目,所以当选择更改时,不必执行任何操作。






可以通过继续多个if / else语句扩展为说9 cbo

我如何保持第一个选项。如果我想包括一个无选项总是可用。



这很多,我会更抽象地做。代码可能更难阅读/跟随,但有较少的(我使用4 cbos)。这可能需要一些调整,因为它是为了修改后的 形式:

 '用于保存CBO的附加数组
Private tgtCBOs As ComboBox()
...
'初始化:
OptList.AddRange(New String(){ ),Red,Green,Blue,Violet,
Orange,Mauve,White})
tgtCBOs = New ComboBox(){cb1,cb2 ,cb3,cb4}

'使用默认项目将初始索引设置为0

私有子cb2_SelectedIndexChanged(发送方作为对象,e作为EventArgs)句柄_
cb2 .SelectedIndexChanged,cb1.SelectedIndexChanged,cb3.SelectedIndexChanged

如果忽略则退出

Dim cbo = TryCast(sender,ComboBox)
'
Dim ndx = Array.IndexOf(tgtCBOs,cbo)
获取从0到这里的所有选择
Dim exclude = GetExclusionList(ndx)
'remove从NEXT cbo中排除
Dim newList As New List(Of String)
如果ndx + 1< tgtCBOs.Length then
newList = OptList.Except(exclude).ToList()
如果newList(0)<>然后newList.Insert(0,(None))
tgtCBOs(ndx + 1).DataSource = newList.ToArray()
End If
End Sub

私有函数GetExclusionList(ndx As Int32)As List(Of String)
Dim exclude As新列表(字符串)
对于n As Int32 = 0到ndx
如果tgtCBOs (n).SelectedIndex<> -1 then
exclude.Add(tgtCBOs(n).Items(tgtCBOs(n).SelectedIndex).ToString())
End If
Next
返回exclude
结束函数

请注意,最后一个cbo未连接到该处理程序,因为它没有 。



此外,还需要重置 DataSource 为下一个(或清除项目的事项)将导致该事件为下一个/子/从CBO启动。因此,更改CBO2将触发事件3,4,5..n。它还会重置子/从/下一个中的先前选择。


I have three combo boxes on a WinForm as the following:

                  ___________________________
ComboBox List 1: |_______________________|___|
                  ___________________________
ComboBox List 2: |_______________________|___|
                  ___________________________
ComboBox List 3: |_______________________|___|

Each of these combo boxes will have, at design-time, a list of "A", "B", "C".

By default, List 1 is the only one active on the form and List 2 and List 3 will become active when its predecessor is given a selection.

What I would like to do, is iF the user choose option C, I would like to have Option C no longer be available for list 2 and 3.

I know this will involve the .SelectedIndexChanged event of the combobox but do not know where to get started with the coding.

I found the following answer on StackOverflow, how my situation doesn't apply since I'm supplying the items at design time and not via an import of a file: vb.net change combobox options depending on selected item in 2 previous comboboxes

解决方案

This is similar to Steve's answer, but uses a DataSource. Also, there is no real need to Enable/Disable each CBO. As they make changes, previous selections are filtered from the source. Any duplicate "previous" changes get undone.

CBO1 always has the full list, while the others omit previous selections. You cant end up with duplicate picks because re-picking #2 to be the same as #3, changes the contents of #3 replacing the selection to whatever is first in the list.

' the master list
Private OptList As New List(Of String)
Private ignore As Boolean

' initialize somewhere:
OptList.AddRange(New String() {"Red", "Green", "Blue", "Violet", "Orange"})
' set up cbos
' ignore changes while setting up:
ignore = True
cb1.DataSource = OptList.ToArray
cb1.SelectedIndex = -1
cb2.DataSource = OptList.ToArray
cb2.SelectedIndex = -1
cb3.DataSource = OptList.ToArray
cb3.SelectedIndex = -1
ignore = False

With them all enabled, they can pick them in any order.

Private Sub cbo_SelectedIndexChanged(sender As Object, e As EventArgs) _
             Handles cb1.SelectedIndexChanged, cb2.SelectedIndexChanged
    If ignore Then Exit Sub

    Dim cbo = TryCast(sender, ComboBox)
    If cbo IsNot Nothing AndAlso cbo Is cb1 Then
        cb2.DataSource = GetFilteredList(New String() {cb1.Items(cb1.SelectedIndex)})
    Else
        cb3.DataSource = GetFilteredList(New String() {cb1.SelectedItem.ToString,
                                                   cb2.SelectedItem.ToString})
    End If
End Sub

Private Function GetFilteredList(items As String()) As String()
    Return OptList.Except(items).ToArray()
End Function

Since cbo3 is limited to those items not picked in #1 or #2 (a slave) you dont have to do anything when that selection changes.


Could this be expanded to say 9 cbo by continuing multiple if/else statements and How would I keep the first option. Say if I wanted to include a "None" option always available.

What that many, I would do it more abstractly. The code may be harder to read/follow, but there is less of it (i was using 4 cbos). This may need some tweaking as it is off the top of my head for the follow up revised form:

' additional array to hold the CBOs involved
Private tgtCBOs As ComboBox()
...
' initialization:
OptList.AddRange(New String() {"(None)", "Red", "Green", "Blue", "Violet", 
                       "Orange", "Mauve", "White"})
tgtCBOs = New ComboBox() {cb1, cb2, cb3, cb4}

' set initial index to 0 with a default item

Private Sub cb2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles _ 
        cb2.SelectedIndexChanged, cb1.SelectedIndexChanged, cb3.SelectedIndexChanged

    If ignore Then Exit Sub

    Dim cbo = TryCast(sender, ComboBox)
    ' identify which one this is
    Dim ndx = Array.IndexOf(tgtCBOs, cbo)
    ' get all the selections from 0 to here
    Dim exclude = GetExclusionList(ndx)
    ' remove excludes from the NEXT cbo
    Dim newList As New List(Of String)
    If ndx + 1 < tgtCBOs.Length Then
        newList = OptList.Except(exclude).ToList()
        If newList(0) <> OptList(0) Then newList.Insert(0, "(None)")
        tgtCBOs(ndx + 1).DataSource = newList.ToArray()
    End If
End Sub

Private Function GetExclusionList(ndx As Int32) As List(Of String)
    Dim exclude As New List(Of String)
    For n As Int32 = 0 To ndx
        If tgtCBOs(n).SelectedIndex <> -1 Then
            exclude.Add(tgtCBOs(n).Items(tgtCBOs(n).SelectedIndex).ToString())
        End If
    Next
    Return exclude
End Function

Note that the last cbo is not connected to that handler because there it has no "slave" . Connect it to its own handler if you need to respond to the event.

Also, the act of resetting the DataSource for the "next" (or clearing Items for that matter) will cause that event to fire for the next/child/slave CBO. So a change to CBO2 will fire the event for 3, 4, 5..n. It also resets the previous selection in the child/slave/next ones.

这篇关于删除或禁用在另一个列表中选择的ComboBox项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆