Как реализовать поиск / фильтр подстроки в WPF Listbox с подсветкой? - PullRequest
2 голосов
/ 06 августа 2010

Народ,

Я пишу небольшое приложение WPF для Windows, у которого есть список, связанный с объектами типа Task.Мне нужно иметь возможность искать и сузить список задач по TaskName.Сужение выделения не является проблемой, но выделение жирным шрифтом совпадающих символов, введенных вами, чтобы сузить выделение.Например, если я получил задачи "Party" и "Painting", набрав "P" и "A", символы должны выделяться жирным шрифтом соответственно.

Как вы видите, моя первоначальная реализация (метод MainWindow_KeyDown ниже) прекрасно работает, тамне был DataTemplate, просто ListBoxItems внутри ListBox.Как мне добиться того же поведения при использовании DataTemplates?

Вот мой шаблон данных, класс задач и реализация поиска.

Спасибо, Хелая

<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));
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...