65.9K
CodeProject is changing. Read more.
Home

Filtered DropDown ComboBox

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4 votes)

Jun 2, 2012

CPOL
viewsIcon

36903

A rather quick and dirty way of creating a filtered combo box in WPF.

I have discovered a rather quick and dirty way of creating a filtered combo box in WPF. It has some quirks, but it is good for longer lists. One issue I discovered was that if I was using the same list for two combo boxes they would interfere with one another. Here is the code behind to handle with combo box:

comboBox1.Loaded += delegate
{
  var textBox1 = (TextBox)comboBox1.Template.FindName(
    "PART_EditableTextBox", comboBox1);
  var popup1 = (Popup)comboBox1.Template.FindName("PART_Popup", comboBox1);

  textBox1.TextChanged += delegate
  {
    popup1.IsOpen = true;
    comboBox1.Items.Filter += a =>
    {
      return textBox1.Text.Length == 0 || (a.ToString().ToUpper().
        StartsWith(textBox1.Text.
        Substring(0, Math.Max(textBox1.SelectionStart, 1)).ToUpper()));
    };
  };
};

In the example I have two combo boxes because I needed two and I was getting some strange behavior between the two. Still get some strange behavior that somebody may be able to figure out.

To do two text boxes I have duplicated code for the lambda expressions. I needed to do this because need to have the parent combo box information when dealing with the TextChanged event. I was unable to figure out how to not duplicate code without some side effects.

The XAML for the form is the following:

<Window x:Class="FilteredComboBoxExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:FilteredComboBoxExample"
        Title="Filtered DropDown ComboBox" Height="200" Width="200">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="80">
    <ComboBox Grid.Column="2"
              Grid.Row="3"
              Name="comboBox1"
              IsEditable="True"
              ItemsSource="{Binding Source={x:Static local:StaticData.GetList}}" />
    <ComboBox Grid.Column="2"
              Grid.Row="4"
              Name="comboBox2"
              IsEditable="True"
              ItemsSource="{Binding Source={x:Static local:StaticData.GetList}}" />
  </StackPanel>
</Window>