【问题标题】:Mutually Exclusive Comboboxes?互斥组合框?
【发布时间】:2014-12-17 07:09:12
【问题描述】:

所以,我有 4 个组合框。它们都共享相同的选项列表,比如说 Apple、Banana、Carrot、Dill。

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

有什么好办法吗?我最初想将框数据源链接到包含选项的列表,但它们需要单独的数据源来进行单独的选择。

单选框和复选框在实际程序中并不是一个真正的选项,因为选项列表远大于 4 个。组合框似乎是代表用户可用选项的最佳方式。

【问题讨论】:

  • 你说他们都共享相同的选项列表并且他们需要单独的数据源来进行单独的选择。所以他们有不同但相同的选择?你的意思是在多个组合框中可能有一些相同的选项,但它们不一定是相同的完整选项列表?
  • 您可以在每次选择后修改数据源。或者向用户展示一个列表,让他们选择订单
  • @ChaseRocker 这些框只需要确保在不同的组合框中永远不会选择相同的项目(排他性)。 IE。 ComboBox1 设置为“Apple”,ComboBox2 设置为“Apple”。这会很糟糕。所以我认为最好的方法是在所有组合框中使用一个可用项目的通用运行列表,并在每次用户选择框中的项目时更改该列表。
  • @Plutonix 如果它们都具有相同的数据源,那么在一个框上进行选择会将所有其他框更改为相同的选择。如果我将框 1 设置为 Apple,那么框 2、3 和 4 也会突然切换到 Apple。
  • 这个帖子已经有几周没有任何活动了。请告诉我们您是如何解决此问题的,或者您是否需要有关此问题的进一步帮助。

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


【解决方案1】:

这是一个相当简单的方法来做你所要求的。此代码假定数据源使用整数值来跟踪项目。如果您使用字符串值本身 {Apple, Banana, etc.} 作为 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

【讨论】:

    猜你喜欢
    • 2015-03-02
    • 2018-11-25
    • 2011-12-26
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多