0

I am currently developing a WPF app in which there are multiple forms to manage a database. One of these forms is a "Add form". This form contains a combobox with some values. Though if the user's wanted value is not in the combobox list, it can be added by selecting the last option which will display a new form for entering the wanted value. If the form is submitted, the last option in the combobox will be changed to this value. The code below describes how this works:

        private void BrandBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
        {

            if (BrandBox.SelectedItem != null &&
                BrandBox.SelectedIndex < BrandBox.Items.Count - 1)
            {
                InitSubCategoryBox(subCatArray[BrandBox.SelectedIndex]);
            }
            else if (BrandBox.SelectedItem != null &&
                     BrandBox.SelectedIndex >= BrandBox.Items.Count - 1) 
            {
                OtherInputWindow newInputForm = new OtherInputWindow("brand", BrandBox.SelectedItem.ToString());

                if (newInputForm.ShowDialog() == true)
                {
                    BrandBox.Items[BrandBox.Items.Count - 1] = newInputForm.returnValue;
                    BrandBox.SelectedIndex = BrandBox.Items.Count - 1;
                }
            } 
        }

The last code line will set the submitted value as selected item. I know this does not work. This last line of code will create a SelectionChanged event and that is exactly what this method is. The result is that it will keep looping and there is no way out. I'm searching for the right way to do this for a long time but I wasn't able yet to find the answer. Hopefully I will find the answer here. Is there someone who can help me solving this problem?

MKlaassen
  • 37
  • 3

1 Answers1

0

I would suggest to not change the SelectedItem from the SelecetionChanged event handler. Instead handle the UIElement.PreviewMouseLeftButtonUp event from the ComboBox:

<ComboBox PreviewMouseLeftButtonUp="OnComboBoxItemPreviewMouseLeftButtonUp" />
private void OnComboBoxItemPreviewMouseLeftButtonUp(object sender, RoutedEventArgs e)
{
  var selector = sender as Selector;
  var clickedItemContainer = Selector.ContainerFromElement(selector, e.OriginalSource as DependencyObject);
  bool isClickTargetItemContainer = clickedItemContainer is not null;
  if (!isClickTargetItemContainer)
  {
    return;
  }

  int selectedIndex = selector.ItemContainerGenerator.IndexFromContainer(clickedItemContainer);
  int lastIndex = selector.Items.Count - 1;
  if (selector.SelectedIndex == lastIndex)
  {
    var newInputForm = new OtherInputWindow("brand", selectedItem.ToString());

    if (newInputForm.ShowDialog() == true)
    {
      selector.Items[lastIndex] = newInputForm.returnValue;
      selector.SelectedIndex = lastIndex;
    }
  }
  else
  {
    InitSubCategoryBox(subCatArray[selector.SelectedIndex]);
  }
}
BionicCode
  • 1
  • 4
  • 28
  • 44
  • Thought this maybe could be the solution. Though now the form is not showing up when I select the last index. Also the other combobox, which have to be filled, is being filled with the wrong values. – MKlaassen Jun 15 '22 at 14:59
  • What do you mean by "now". It was working before, right? What have you changed? And where does the second ComboBox come from? It's not part of your question. Then how can I know what you are doing with a second ComboBox? – BionicCode Jun 15 '22 at 15:16
  • I'm verry sorry for the confusion. Forget the second combobox for now. I've deleted the SelectionChanged event and tried to make it work with the PreviewMouseLeftButtonUp event like you showed. But then when I select the last item in the combobox, the form does not appear. – MKlaassen Jun 15 '22 at 17:14
  • Don't worry. Is the event handler called? – BionicCode Jun 15 '22 at 17:42
  • I have reviewed my code and found an error. Since we are handling the selection outside the SelectionChanged event, actually prior to it being raised, the value returned by `selector.SelectedIndex` is never correct. It will always show the last selected index. I have added a line to obtain the correct index of the clicked item. Let me know if is working now, please. – BionicCode Jun 15 '22 at 18:01
  • Ahh I understand the error. Though it is still not working. The result is still the same. – MKlaassen Jun 15 '22 at 20:11
  • I have just tested the code and it operates as expected: I enter the `if (selector.SelectedIndex == lastIndex)` section only when the last ComboBox item is clicked. Can you please verify that this is the case when you execute it? Chances are that you return from the method at line `if (!isClickTargetItemContainer)`. – BionicCode Jun 15 '22 at 20:43
  • I think that last one is the case. The combobox displays the selected item but the event that is supposed to happen when the last index is selected, is not happening. Though I understand your code I'm not quite sure how to fix this. – MKlaassen Jun 17 '22 at 06:45
  • No Problem. But the event handler is called? This is important to know. It would be great if you are able to debug the handler. Like place break points in each conditional code block to step through there code in order to know if the handler is invoked and which path is actually executed. – BionicCode Jun 17 '22 at 10:22
  • I found out that the handler was not called. So I've started overnew by making a new handler. Now it is called but doesn't behave like I wanted to. When I select te last item in the combobox, the new form does not appear. It does when I select a random value of the combobox straight after. Then every index of the combobox makes the form appear. – MKlaassen Jun 22 '22 at 06:36
  • The posted example behaves as expected: clicking the last item will execute the if-branch (where the dialog is loaded) and clicking any other item will execute the else-branch. If you need more help, would you mind to update your question and post your current version (including the ComboBox)? So I am able to review the relevant code that is related to the behavior. – BionicCode Jun 22 '22 at 10:56
  • Found out I made a small error while writing the code. I fully copied your code and pasted it and now it works indeed as it should work. I'm sorry for the confusion. Thanks for helping me out! – MKlaassen Jun 28 '22 at 08:51