Tutorial :How to implement substring search / filter in WPF Listbox with highlighting?



I am writing a small WPF Windows App which has a listbox bound to Task type objects. I need to be able to search and narrow down the list of Tasks by TaskName. Narrowing down the selection isn't the problem, but bolding the matching characters you typed to narrow down the selection is. For an example if I got tasks "Party" and "Painting" typing "P" and "A" should bold the characters respectively.

As you would see my initial implementation (MainWindow_KeyDown method below) works great, there wasn't a DataTemplate, just ListBoxItems inside the ListBox. How can I achieve the same behavior with using DataTemplates ?

Here is my data template, Task class and the search implementation.

Thanks, Helaya

<DataTemplate DataType="{x:Type Model:Task}">      <Grid x:Name="grid1">          <Grid.ColumnDefinitions>              <ColumnDefinition Width="40"/>              <ColumnDefinition Width="140"/>          </Grid.ColumnDefinitions>          <Grid.RowDefinitions>              <RowDefinition Height="auto"/>          </Grid.RowDefinitions>          <TextBlock Grid.Column="0" Grid.Row="0" Name="t1" Text="*" Padding="0,5" HorizontalAlignment="Left" VerticalAlignment="Center" TextWrapping="Wrap"></TextBlock>          <TextBlock Grid.Column="1" Grid.Row="0" Name="TaskName" Text="{Binding TaskName}" Padding="0,5" HorizontalAlignment="Left" VerticalAlignment="Center" TextWrapping="Wrap"></TextBlock>                  </Grid>  </DataTemplate>  

public class Task  {      public string TaskName { get; set; }      public string Description { get; set; }      public string Priority { get; set; }  }  

    private StringBuilder filterText = new StringBuilder();            void MainWindow_KeyDown(object sender, KeyEventArgs e)      {          string key = null;            if (e.Key != Key.Back)          {              key = e.Key.ToString();              filterText.Append(key);          }          else          {              if (filterText.Length > 0)                  filterText.Remove(filterText.Length - 1, 1);          }            foreach (ListBoxItem item in listBox1.Items)          {              int index = 0;              TextBlock textblock = (TextBlock)item.Content;              string str = textblock.Text;                if ((index = str.IndexOf(filterText.ToString(), StringComparison.CurrentCultureIgnoreCase)) != -1)              {                  textblock.Text = null;                  Bold b = new Bold();                  b.Inlines.Add(new Run(str.Substring(index, filterText.Length)));                  textblock.Inlines.Add(b);                    if (str.Length > filterText.Length)                      textblock.Inlines.Add(str.Substring(filterText.Length));              }          }      }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »