none
Focus issues with Editable ComboBox

    Question

  • I am having focus issues with combo boxes that have their IsEditable property set to true. The issues go away as soon as I set the property to false.

    First, with IsEditable set to true the IsFocused property is never ever true.

    Second, with the IsEditable property set to true, whenever I put the focus on the combo box, either manually through the UI or through code the combo box first fires the LostFocus event and then the GotFocus event. Even in the GotFocus event the IsFocused property if false! Again, set IsEditable property to false and focus works as expected. Only GotFocus is called and the IsFocused property is correctly set to true.

    When IsEditable is set to true I am able to enter characters into the text box portion of the combo box. The combo box will initially have no items, its going to be used to maintain a history of entered items, however I have tested with a pre-populated combo box and get the same behavior.

    I have reproduced this behavior in a simple one window one control wpf app.

    Additionally, I noticed that when I had IsEditable set to false and would mouse over the drop down list to select an item, the combo box was losing and geting focus. What the heck?

    Any suggestions would be greatly appreciated. At the moment it looks like I have to create my own combo box.

    We are not using focus groups.

    Here is the XAML for my combo box.
    <ComboBox HorizontalAlignment="Stretch" Margin="10,3,3,3" VerticalAlignment="Center" IsSynchronizedWithCurrentItem="True"  Grid.Column="1" MinWidth="100" IsEditable="True" TabIndex="0" IsTabStop="True" Name="ApplicationServerComboBox" SelectionChanged="ApplicationServerComboBox_SelectionChanged" IsTextSearchEnabled="True" LostFocus="ApplicationServerComboBox_LostFocus" GotFocus="ApplicationServerComboBox_GotFocus" />

    Edit: I just did another test with IsEditable set to true: Keyboard.FocusedElement tells me TextBox has the keyboard focus.

    Isn't this supposed to get routed to the parent? The name of the TextBox is PART_EditableTextBox.
    Thursday, June 11, 2009 3:07 PM

Answers


  • Hello Seamus,

    ComboBox is a nasty control and you likely won't have much fun re-writing it ;o).

    I think with the LostFocus, GotFocus thing you're seeing is that there are multiple parts to the combobox, so as the control deals with sorting out who is in focus internally you see a bit of fakeness to it...so you get the GotFocus, but really, it's not focused.

    That's because it's the textbox inside the combobox that has focus.

    In your window constructor, try this:
                this.ApplicationServerComboBox.Loaded += delegate
                {
                    TextBox tb = (TextBox)ApplicationServerComboBox.Template.FindName("PART_EditableTextBox", ApplicationServerComboBox);
                    if (tb!=null)
                    {
                        tb.GotFocus += new RoutedEventHandler(tb_GotFocus);
                    }
                };
    And add a method to your class as such:
            void tb_GotFocus(object sender, RoutedEventArgs e)
            {
                TextBox tb = sender as TextBox;
                Console.WriteLine("-> Textbox GotFocus (IsFocused:{0})",tb.IsFocused);
            }

    Now, if you check your output window at run time, you'll see your textbox catch focus.

    Can you latch onto THAT GotFocus event?

    Cheers,
    -jc

    Me, coding and stuff: Mr. James
    • Proposed as answer by JamesChambers Thursday, June 11, 2009 6:20 PM
    • Marked as answer by Zhi-Xin Ye Friday, June 12, 2009 11:57 AM
    Thursday, June 11, 2009 3:56 PM

All replies


  • Hello Seamus,

    ComboBox is a nasty control and you likely won't have much fun re-writing it ;o).

    I think with the LostFocus, GotFocus thing you're seeing is that there are multiple parts to the combobox, so as the control deals with sorting out who is in focus internally you see a bit of fakeness to it...so you get the GotFocus, but really, it's not focused.

    That's because it's the textbox inside the combobox that has focus.

    In your window constructor, try this:
                this.ApplicationServerComboBox.Loaded += delegate
                {
                    TextBox tb = (TextBox)ApplicationServerComboBox.Template.FindName("PART_EditableTextBox", ApplicationServerComboBox);
                    if (tb!=null)
                    {
                        tb.GotFocus += new RoutedEventHandler(tb_GotFocus);
                    }
                };
    And add a method to your class as such:
            void tb_GotFocus(object sender, RoutedEventArgs e)
            {
                TextBox tb = sender as TextBox;
                Console.WriteLine("-> Textbox GotFocus (IsFocused:{0})",tb.IsFocused);
            }

    Now, if you check your output window at run time, you'll see your textbox catch focus.

    Can you latch onto THAT GotFocus event?

    Cheers,
    -jc

    Me, coding and stuff: Mr. James
    • Proposed as answer by JamesChambers Thursday, June 11, 2009 6:20 PM
    • Marked as answer by Zhi-Xin Ye Friday, June 12, 2009 11:57 AM
    Thursday, June 11, 2009 3:56 PM
  • Thanks Jame, I'll try your suggestion.

    Ultimately its the IsFocused property and LostFocus event that we are interested in.

    We want to give the user the ability to enter any string in the combo box. If it doesn't match an item in the list that's ok, it's potentially a new item. In fact its a machine name. We're simply using the drop down list to provide a history of entered and successfully used machine names.

    Firstly, we'll handle the selection changed event as normally expected.

    If the user hits the enter key, and this control has the focus we are going to attempt to get a list of items based on what's in the text box and populate another combo box with that list. Of course we'll make sure we didn't already do this based on the selection changed event.

    In order to process the enter key correctly we were going to check ApplicationServerComboBox.IsFocused because we process the enter key differently depending on what control has the focus.

    Additionally we would need to process the LostFocus event.

    We need to be able to get input from either a selection or what is entered by the user. Isn't this the point of the combo box? With its default behavior its not possible.

    Anyhoo, thanks for the input and I'll give it a spin.

    Thursday, June 11, 2009 4:45 PM
  • Again, thanks James. Your snippet has provided the solution I needed.
    Thursday, June 11, 2009 5:39 PM
  • No worries! Glad I could help.

    Cheers,
    -jc

    Me, coding and stuff: Mr. James
    Thursday, June 11, 2009 6:21 PM

  • Thanks JamesChambers. you are great. it works perfectly
    Wednesday, May 29, 2013 11:37 AM