互斥组合框架?

时间:2014-12-16 21:52:00

标签: vb.net visual-studio-2012 combobox

所以,我有4个Comboboxes。它们都有相同的选项列表,比如Apple,Banana,Carrot,Dill。

但是,一旦用户选择了一个,那么其他组合框中就不应该有这种选择。例如。如果他们在Combobox1中挑选Apple,那么Combobox2,3和4中唯一可用的选项应该是Banana,Carrot和Dill。

这样做有好办法吗?我原本以为将数据源框链接到包含选项的列表,但是它们需要单独的数据源来进行单独的选择。

实际程序中的收音机和复选框实际上不是一个选项,因为选项列表远大于4. Combobox似乎是表示用户可用选项的最佳方式。

1 个答案:

答案 0 :(得分:0)

这是一个相当简单的方法来做你要求的事情。此代码假定数据源使用整数值来跟踪项目。如果您使用字符串值本身{Apple,Banana等}作为id,则需要稍微修改代码。如果您需要进一步的帮助,请告诉我,但希望这能让您走上正确的道路。

您可以通过创建一个新的空白表单(Form1)并在其上放置4个组合框(ComboBox1,ComboBox2,ComboBox3,ComboBox4)来测试它。将此代码复制/粘贴到表单代码的顶部,然后运行以查看其工作原理:

Public Class Form1
    Dim oComboBoxArray(3) As ComboBox
    Dim bPreventSelectedChange As Boolean = False

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Set up an array with the combo box references to reduce code size by using loops later

        oComboBoxArray(0) = Me.ComboBox1
        oComboBoxArray(1) = Me.ComboBox2
        oComboBoxArray(2) = Me.ComboBox3
        oComboBoxArray(3) = Me.ComboBox4

        ' Populate all four combo boxes with the same datasource to start

        For Each oCbo In oComboBoxArray
            PopulateDataSource(oCbo)
        Next
    End Sub

    Private Sub PopulateDataSource(oCombo As ComboBox, Optional nIdToSelect As Integer = 0)
        bPreventSelectedChange = True   ' Prevent code in ComboBox_SelectedIndexChanged from executing while we change the datasource

        ' Using manually populated datatable as datasource because it's quick and easy to use

        Dim dt As New DataTable
        Dim dr As DataRow

        dt.Columns.Add("ID", GetType(Int32))
        dt.Columns.Add("Name", GetType(String))

        ' Need to have some kind of "Please select an item:" in the list or else we will be unable to clear an already selected combo box

        dr = dt.NewRow
        dr("ID") = 0
        dr("Name") = "Select..."
        dt.Rows.Add(dr)

        ' If you are populating from a database or other dynamic source you will only have one of these 'if' statements within a loop

        If CheckSkipItem(oCombo, 1) = False Then
            dr = dt.NewRow
            dr("ID") = 1
            dr("Name") = "Apple"
            dt.Rows.Add(dr)
        End If

        If CheckSkipItem(oCombo, 2) = False Then
            dr = dt.NewRow
            dr("ID") = 2
            dr("Name") = "Banana"
            dt.Rows.Add(dr)
        End If

        If CheckSkipItem(oCombo, 3) = False Then
            dr = dt.NewRow
            dr("ID") = 3
            dr("Name") = "Carrot"
            dt.Rows.Add(dr)
        End If

        If CheckSkipItem(oCombo, 4) = False Then
            dr = dt.NewRow
            dr("ID") = 4
            dr("Name") = "Dill"
            dt.Rows.Add(dr)
        End If

        oCombo.DataSource = dt
        oCombo.DisplayMember = "Name"
        oCombo.ValueMember = "ID"
        oCombo.SelectedValue = nIdToSelect  ' Set value to either a) the "Select..." item or b) the item that was selected previously depending on the situation

        bPreventSelectedChange = False   ' Allow code in ComboBox_SelectedIndexChanged to be executed by user again
    End Sub

    Private Function CheckSkipItem(oCombo As ComboBox, nID As Integer) As Boolean
        Dim bSkip As Boolean = False

        ' Loop through all combo boxes and see if this id has already been chosen in another combo box

        For Each oCbo In oComboBoxArray
            If oCbo IsNot oCombo AndAlso oCbo.SelectedValue = nID Then
                ' It has been chosen already so it is not valid for the current combo box that we are checking

                bSkip = True
                Exit For
            End If
        Next

        Return bSkip
    End Function

    Private Sub ComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged, ComboBox2.SelectedIndexChanged, ComboBox3.SelectedIndexChanged, ComboBox4.SelectedIndexChanged
        ' Jump out of this event if the bPreventSelectedChange boolean is set to true (ie. if the combo box is being repopulated)

        If bPreventSelectedChange = False Then
            ' A value was chosen by the user. Reset all other combo box datasources and remove the recently selected value

            For Each oCbo As ComboBox In oComboBoxArray
                If sender IsNot oCbo Then
                    PopulateDataSource(oCbo, If(oCbo.SelectedValue = Nothing, 0, oCbo.SelectedValue))
                End If
            Next
        End If
    End Sub
End Class