Home > Software design >  C# dependent comboboxes fire events
C# dependent comboboxes fire events

Time:08-19

I need some help. I have 4 comboboxes which depends on each other (building; room; shelf; box).

If I do the SelectedIndexChange of the (first) building combobox, all other comboboxes get the top value of each box and the filter is not only set of the building, it is set over all four comboboxes.

    void StartFilter()
    {
        placesRepository = new PlacesRepository();

        cbBuilding.DataSource = null;
        cbBuilding.Items.Clear();
        cbBuilding.DataSource = placesRepository.AllBuilding();
        cbBuilding.DisplayMember = "Building";
        cbBuilding.ValueMember = "BuildingId";

        dgAll.DataSource = placesRepository.AlleStoragePlaces();

    }
    private void cbBuilding_SelectedIndexChanged(object sender, EventArgs e)
    {           
        if (cbBuilding.SelectedItem is Places building)
        {
            if (building != null)
            {
                dgAll.DataSource = null;
                dgAll.DataSource = placesRepository.AllStoragePlacesForBuilding(building.BuildingNumber);

                cbRoom.DataSource = null;
                cbRoom.Items.Clear();
                cbRoom.DataSource = placesRepository.AlleRoomsForBuilding(building.BuildingNumber);
                cbRoom.DisplayMember = "Room";
                cbRoom.ValueMember = "RoomNumber";
                if (cbRoom.Items.Count > 0)
                {
                    fireEvent = false;
                    cbRoom.SelectedIndex = -1;
                    fireEvent = true;
                }
            }
        }
    }
    private void cbRoom_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (!fireEvent)
            return;
        else
        {
            if (cbRoom.SelectedItem is Places room)
            {
                if (room != null)
                {
                    dgAll.DataSource = null;
                    dgAll.DataSource = placesRepository.AllStorgaePlacesForRoomAndBuilding(room.BuildingNumber, room.RoomNumber);

                    cbShelf.DataSource = null;
                    cbShelf.Items.Clear();
                    cbShelf.DataSource = placesRepository.AllShelfsForRoomAndBuilding(room.BuildingNumber, room.RoomNumber);
                    cbShelf.DisplayMember = "Shelf";
                    cbShelf.ValueMember = "Shelf";
                    if (cbShelf.Items.Count > 0)
                    {
                        fireEvent = false;
                        cbShelf.SelectedIndex = -1;
                        fireEvent = true;
                    }
                }
            }
        }            
    }
    private void cbShelf_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (!fireEvent)
            return;
        else
        {
            if (cbShelf.SelectedItem is Places shelf)
            {
                if (shelf != null)
                {
                    dgAll.DataSource = null;
                    dgAll.DataSource = placesRepository.AllStorgaePlacesForShelfRoomAndBuilding(shelf.BuildingNumber, shelf.RoomNumber, shelf.Shelf);

                        ...
                }
            }
        }
    }
    private void cbLageruebersichtFach_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (!fireEvent)
            return;
        else
        {
            ....
        }

I tried to fix the problem by using the fireEvent but this doesn't show any effect. So, what is wrong?

CodePudding user response:

Tested try

Setting the ComboBox.DataSource property triggers its SelectedIndexChanged event, so

private void cbBuilding_SelectedIndexChanged(object sender, EventArgs e)
{           
    if (cbBuilding.SelectedItem is Places building)
    {
        if (building != null)
        {
            
            dgAll.DataSource = null;
            dgAll.DataSource = placesRepository.AllStoragePlacesForBuilding(building.BuildingNumber);
            
            fireEvent = false; // We don't want to do trigger the evnts down the line yet.

            cbRoom.DataSource = null;
            cbRoom.Items.Clear();
            cbRoom.DataSource = placesRepository.AlleRoomsForBuilding(building.BuildingNumber);
            cbRoom.DisplayMember = "Room";
            cbRoom.ValueMember = "RoomNumber";
            if (cbRoom.Items.Count > 0)
            {
                
                cbRoom.SelectedIndex = -1;
               
            }
            fireEvent = true;// we want events to fire again
        }
    }
}
private void cbRoom_SelectedIndexChanged(object sender, EventArgs e)
{
    if (!fireEvent)
    {
        return; 
    }
    else //...

This behavior happens on both .NET Framework 4.7.2. and .NET Core 3.1


Didn't work.

First try

From the sound of it, it looks as if the events are triggered by setting the ComboBox.SelectedIndex =-1, but they only execute after the first event handler has exited.

The following code doesn't work because ripping the elements off triggers the
ComboBox.SelectedIndexChanged

private void cbBuilding_SelectedIndexChanged(object sender, EventArgs e)
{           
    if (cbBuilding.SelectedItem is Places building)
    {
        if (building != null)
        {
            dgAll.DataSource = null;
            dgAll.DataSource = placesRepository.AllStoragePlacesForBuilding(building.BuildingNumber);

            cbRoom.DataSource = null;
            cbRoom.Items.Clear();
            cbRoom.DataSource = placesRepository.AlleRoomsForBuilding(building.BuildingNumber);
            cbRoom.DisplayMember = "Room";
            cbRoom.ValueMember = "RoomNumber";
            if (cbRoom.Items.Count > 0)
            {
                fireEvent = false;
                cbRoom.SelectedIndex = -1;
               // fireEvent = true; // Not yet
            }
        }
    }
}
private void cbRoom_SelectedIndexChanged(object sender, EventArgs e)
{
    if (!fireEvent)
    {
        fireEvent = true; // we want events to fire again
        return; 
    }
    else // ...
  • Related