WPF: Dropdown of a Combobox highlightes the text

I had this very same issue and like some of the users being new to WPF, struggled to get the solution given by Einar Guðsteinsson to work. So in support of his answer I'm pasting here the steps to get this to work. (Or more accurately how I got this to work).

First create a custom combobox class which inherits from the Combobox class. See code below for full implementation. You can change the code in OnDropSelectionChanged to suit your individual requirements.

namespace MyCustomComboBoxApp { using System.Windows.Controls;

public class MyCustomComboBox : ComboBox
{
    private int caretPosition;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        var element = GetTemplateChild("PART_EditableTextBox");
        if (element != null)
        {
            var textBox = (TextBox)element;
            textBox.SelectionChanged += OnDropSelectionChanged;
        }
    }

    private void OnDropSelectionChanged(object sender, System.Windows.RoutedEventArgs e)
    {
        TextBox txt = (TextBox)sender;

        if (base.IsDropDownOpen && txt.SelectionLength > 0)
        {
            txt.CaretIndex = caretPosition;
        }
        if (txt.SelectionLength == 0 && txt.CaretIndex != 0)
        {
            caretPosition = txt.CaretIndex;
        }
    }

}

Ensure that this custom combo class exists in the same project. THen you can use the code below to reference this combo in your UI.

<Window x:Class="MyCustomComboBoxApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cc="clr-namespace:MyCustomComboBoxApp"
    Title="MainWindow" Height="350" Width="525" FocusManager.FocusedElement="{Binding ElementName=cb}">
<Grid>
    <StackPanel Orientation="Vertical">
        <cc:MyCustomComboBox x:Name="cb" IsEditable="True" Height="20" Margin="10" IsTextSearchEnabled="False" KeyUp="cb_KeyUp">
            <ComboBoxItem>Toyota</ComboBoxItem>
            <ComboBoxItem>Honda</ComboBoxItem>
            <ComboBoxItem>Suzuki</ComboBoxItem>
            <ComboBoxItem>Vauxhall</ComboBoxItem>
        </cc:MyCustomComboBox>
    </StackPanel>
</Grid>
</Window>

Thats it! Any questions, please ask! I'll do my best to help.

THanks to Einar Guðsteinsson for his solution!


Better late than never and if some one else hit this proplem he might use this.

There is away todo this if you override combobox. First get handle on the textbox that is used in the template and register to selectionchanged event.

public override void OnApplyTemplate()
{
  base.OnApplyTemplate();

  var element = GetTemplateChild("PART_EditableTextBox");
  if (element != null)
  {
    var textBox = (TextBox)element;
    textBox.SelectionChanged += OnDropSelectionChanged;
  }
}

private void OnDropSelectionChanged(object sender, RoutedEventArgs e)
{
    // Your code
}

Then in the event handler you can set the selection again like you want it to be. In my case I was calling IsDropDownOpen in code. Saved selection there then put it back in the event handler. Ugly but did the trick.

Tags:

C#

Wpf

Combobox