2

I have the following properties set on my combobox-

    <ComboBox ItemsSource="{Binding AllLines, Mode=OneWay}" Grid.Column="1" SelectedItem="{Binding SelectedLine}" Margin="4"
              Visibility="{Binding ShowLines, Converter={StaticResource BoolToVisible}}" AlternationCount="2"
              IsTextSearchEnabled="True" IsEditable="True" TextSearch.TextPath="SearchText" IsTextSearchCaseSensitive="False"
              ItemContainerStyle="{StaticResource alternatingWithTriggers}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Margin="2,0,2,0" FontWeight="Bold" Text="{Binding Description}"
                               Visibility="{Binding Description, Converter={StaticResource NullVisibilityConverter}}"></TextBlock>
                    <TextBlock Margin="2,2,2,4" Text="{Binding Designator}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>                
    </ComboBox>

Following the suggestion outlined here I added a custom Search property that included the three properties I wanted to search against. WPF: Changing a ComboBox's ItemTemplate removes the ability to jump down the list as you type. Any way to fix this?

public string SearchText {get { return string.Format("{0} | {1} | {2}", Description, ID, Designator); }}

My question is, can I do a wildcard or substring search on my concatenation of properties?

Community
  • 1
  • 1
Darlene
  • 808
  • 5
  • 16

2 Answers2

3

Found an idea here from which I modeled my solution- http://jacobmsaylor.com/?p=17

I made some small changes such as listening to the KeyUp instead of the KeyDown and making the filter case-insensitive. I also added a check to make sure that the combo box text (the search text) was not null or empty.

In the code behind-

public SelectRouteSegmentDialog()
{
    InitializeComponent();

    LineComboBox.Items.Filter += FilterPredicate;
}

private bool FilterPredicate(object obj)
{
    Line line = obj as Line;
    if (string.IsNullOrEmpty(LineComboBox.Text)) return true;

    if (line.SearchText != null)
    {
        if (line.SearchText.IndexOf(LineComboBox.Text, StringComparison.CurrentCultureIgnoreCase) >= 0)
        {
            return true;
        }
        return false;
    }
    else
    {
        //if the string is null, return false
        return false;
    }

}

private void combobox_KeyUp(object sender, KeyEventArgs e)
{
    if ((e.Key == Key.Enter) || (e.Key == Key.Tab) || (e.Key == Key.Return))
    {
        //Formatting options
        LineComboBox.Items.Filter = null;
    }
    else if ((e.Key == Key.Down) || (e.Key == Key.Up))
    {
        LineComboBox.IsDropDownOpen = true;
    }
    else
    {
        LineComboBox.IsDropDownOpen = true;
        LineComboBox.Items.Filter += this.FilterPredicate;
    }
}

And the xaml I set IsEditable=true, IsTextSearchEnabled=false and TextSearch.TextPath equal to the path I wanted displayed for my selected item (otherwise just the ToString was displayed). I also listend to the key up event-

   <ComboBox ItemsSource="{Binding AllLines, Mode=OneWay}" Grid.Column="1" SelectedItem="{Binding SelectedLine}" Margin="4"
             Visibility="{Binding ShowLines, Converter={StaticResource BoolToVisible}}" AlternationCount="2"
              IsEditable="True" TextSearch.TextPath="SearchText" IsTextSearchEnabled="False"
              ItemContainerStyle="{StaticResource alternatingWithTriggers}" x:Name="LineComboBox" KeyUp="combobox_KeyUp">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Margin="2,0,2,0" FontWeight="Bold" Text="{Binding DisplayText}"
                               Visibility="{Binding Description, Converter={StaticResource NullVisibilityConverter}}"></TextBlock>
                    <TextBlock Margin="2,2,2,4" Text="{Binding Designator}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>                
    </ComboBox>
Darlene
  • 808
  • 5
  • 16
1

My question is, can I do a wildcard or substring search on my concatenation of properties?

Not using the built-in TextSearch mechanism; it's a prefix match only. You can specify the text directly, or provide the path to the property containing the text (as you have done), but you cannot change the matching behavior.

You will have to implement your own text search mechanism to get the kind of behavior you want. Try exploring the TextSearch source code for implementation ideas.

Mike Strobel
  • 25,075
  • 57
  • 69