How to fix this combobox index change problem?

Hobbyist_programmer 621 Reputation points
2021-04-02T12:05:32.677+00:00

Hallo,

I don't know how to describe this problem . Here is my sample code and as you can see from the gif when i add an object to the project list, the combo box index changed and it shows empty. I want combobox to show the first item always. Why this is happening and how can i prevent it?.

I know i can set the index to 0 after adding a project. but i have lot of combo boxes like this in other object is there any proper way to fix it or any alternative? Thanks

84042-sample.gif

Imports System.ComponentModel  
  
Public Class Form1  
  
    Public BL_Projects As New Projects  
    Public BS_Projects As New BindingSource  
  
    Public BS_MyObjects As New BindingSource  
  
    Public BL_CBItems As New CBItems  
    Public BS_CBItems As New BindingSource  
  
  
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load  
  
        BL_CBItems.Add(New CBItem With {.ID = 1, .Name = "Item1"})  
        BL_CBItems.Add(New CBItem With {.ID = 2, .Name = "Item2"})  
        BL_CBItems.Add(New CBItem With {.ID = 3, .Name = "Item3"})  
        BL_CBItems.Add(New CBItem With {.ID = 4, .Name = "Item4"})  
  
        BS_CBItems.DataSource = BL_CBItems  
  
        With ComboBox1  
            .DisplayMember = "Name"  
            .ValueMember = "ID"  
            .DataSource = BS_CBItems  
        End With  
  
        BS_Projects.DataSource = BL_Projects  
        DataGridView1.DataSource = BS_Projects  
  
        BS_MyObjects.DataSource = BS_Projects  
        BS_MyObjects.DataMember = "MyObjects"  
        DataGridView2.DataSource = BS_MyObjects  
  
  
        ComboBox1.DataBindings.Add("SelectedValue", BS_MyObjects, "ID", True, DataSourceUpdateMode.OnPropertyChanged)  
  
  
    End Sub  
  
    Private Sub Add_Project_Click(sender As Object, e As EventArgs) Handles Add_Project.Click  
        BS_Projects.Add(New Project With {.ID = 1, .Name = "Project1"})  
    End Sub  
  
    Private Sub Add_MyObject_Click(sender As Object, e As EventArgs) Handles Add_MyObject.Click  
        BS_MyObjects.Add(New MyObject With {.ID = 1})  
    End Sub  
  
End Class  
  
  
  
  
Public Class Project  
    Public Sub New()  
    End Sub  
    Public Property ID As Integer  
    Public Property Name As String  
    Public Property MyObjects As New MyObjects  
End Class  
Public Class Projects  
    Inherits System.ComponentModel.BindingList(Of Project)  
End Class  
  
  
  
Public Class MyObject  
    Public Sub New()  
    End Sub  
    Public Property ID As Integer  
    Public Property MyObjectName As String  
End Class  
Public Class MyObjects  
    Inherits System.ComponentModel.BindingList(Of MyObject)  
End Class  
  
  
  
Public Class CBItem  
    Public Property ID As Integer  
    Public Property Name As String  
End Class  
Public Class CBItems  
    Inherits System.ComponentModel.BindingList(Of CBItem)  
End Class  
Developer technologies | VB
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Michael Taylor 60,161 Reputation points
    2021-04-02T14:22:44.587+00:00

    I think I understand your problem and the short answer is no, there is no automated way to fix this. But you might be able to get it to work the way you want by making some adjustments.

    To be clear though I don't understand the relationship between projects and items in your combo box. Based upon your types it appears that a project contains objects so the user will select the projects in the left grid and then see the project's objects in the right one. I'm not clear how the combo box fits into this. At this point, perhaps for testing, you are using the fixed list of 4 items. How those items relate to anything in the second grid is beyond me. I'm wondering if at some point a project will contain a set of items and each item will then contain a set of objects. If that were the case then data binding should be able to replicate what you want. But for now I'll assume that every project has a set of 4 items and they have nothing to do with objects in the grid. You just want to reset to the first item when a new project is added.

    I haven't tested it but you might be able to use the BindingNavigator to solve this problem. Or perhaps the CurrencyManager on the binding source you're using. The navigator would "navigate" the projects in the grid. Whenever the current object changes the combo box would update with the current project's items. You likely would need a separate navigator for the objects on the right (cascading navigators) if you needed to track the selected item there as well.

    Going back to your problem though you are binding the combo's SelectedValue to the ID of the BS_MyObjects so when the project changes the selected value of the combo changes. The problem is that they might not line up at all given you are currently stubbing in the values. Even then though it doesn't seem like it'll work properly. I think here is a good place to adjust your data to fit the UI needs (note: this is why UI patterns tend to use models instead of the raw data). Add a project to your Project type that represents the currently selected CBItem's ID (which you can just set to 1 and leave if you want). Then bind to that in the combo box. Then when the selected project changes it should reset to the project's CBItem selected.

    Personally I don't like Winforms data binding so I don't use it as it is limited to me. So an alternative approach is to hook up the combo box's SelectedIndexChanged event and if it is less than 0 (and not empty) then reset it to 0 which should force it to always select the first item. Note that you'll also want to set the combo boxes's DropDown style to DropDownList.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.