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>