You find yourself using WPF and you have a ComboBox bound to some data source. Your users can type what they need in the ComboBox and with the IsTextSearchEnabled and IsEditingEnables properties set to true, they can type the first few letters of the word they are searching for and the ComboBox jumps to whatever matching words start with the user's search term.
But, what if, in this combobox with an unorthodox amount of data in it, the user needs to be able to type a keyword and both be able to hide unmatched entries and have more complex searching such as filtering by object properties in the data source or showing search terms that occur anywhere in the DisplayMember property? Lambda's to the rescue!
You can hook an event up to the ComboBox's KeyUp event and apply a filter to the Items property of the ComboBox.
So, our XAML would look something like this:
<ComboBox IsEditable="True" IsTextSearchEnabled="True" ItemsSource="{Binding ComboBoxDataSource}" KeyUp="ComboBox_KeyUp" Text="{Binding SelectedItemText, UpdateSourceTrigger=PropertyChanged}">and in our XAML codebehind, we would have the ComboBox_KeyUp event handler as follows:
private void ComboBox_KeyUp(object sender, KeyEventArgs e) { // Ignore the user trying to scroll through filtered items using the up/down key. var key = e.Key; if(key == Key.Up || key == Key.Down) return; var cbo = (ComboBox)sender; var search = cbo.Text ?? String.Empty; cbo.IsDropDownOpen = true; cbo.Items.Filter = item => item.ToString().ToLower().Contains(search.ToLower()); }
So, in this code, we are taking the text that the user typed into the editable combobox and setting it to an empty string if it's null.
Then we assign a lambda expression which takes an object - called item - and check to see if the text that the user typed in, ignoring case, exists in the item.
Simple as that.