Text Highlight in WPF

Whenever there is a search scenario or filter situation, it would be really good if the filtered text will highlight in the given result. In Windows 8 search, this is the case and it looks good. But the bad thing is, Microsoft does not provide a direct way to highlight a specific text in textblock. But it is still doable with some extra coding.

I have created a simple Behavior which will achieve the above requirement. Here we have a dependency property to track the query text. Whenever the query text change, the behavior will refresh. The original text should be divided into 3 pieces based on the query text.

texthighlight1

Three Run objects should be created holding text of each piece as shown above. The three Runs should be added into Inlines collection of textblock. The second piece which is query text should be decorated with highlight style. The behavior is holding dependency properties to decorate it.

        private void OnTextChanged()
        {
            if (this.AssociatedObject != null)
            {
                string actualText = this.AssociatedObject.Text;
                string queryText = this.Text;
                if (actualText.ToLower().Contains(queryText.ToLower()))
                {
                    int index = actualText.IndexOf(queryText, StringComparison.InvariantCultureIgnoreCase);
                    string run1 = actualText.Substring(0, index);
                    string run2 = actualText.Substring(index, queryText.Length);
                    string run3 = actualText.Substring(index + queryText.Length);

                    var newRun1 = new Run(run1);
                    var newRun2 = new Run(run2) { Foreground = Foreground, Background = Background };
                    var newRun3 = new Run(run3);

                    this.AssociatedObject.Inlines.Clear();
                    this.AssociatedObject.Inlines.Add(newRun1);
                    this.AssociatedObject.Inlines.Add(newRun2);
                    this.AssociatedObject.Inlines.Add(newRun3);
                }
            }
        }

Declaring this in XAML is simple as below,

<TextBlock Text="{Binding Email}"
            VerticalAlignment="Top"
            Margin="3 0"
            Grid.Column="1"
            Grid.Row="1">
    <i:Interaction.Behaviors>
        <local:TextHighlightBehavior Text="{Binding ElementName=searchTxt, Path=Text}"
                                        Background="{x:Static SystemColors.HighlightBrush}" />
    </i:Interaction.Behaviors>
</TextBlock>

Download Sample

texthighlight2

Leave a comment

Up ↑