A Silverlight HighlightingTextBlock implemented in Visual Basic
Using the same steps and control template XAML from my earlier post today about the HighlightingTextBlock control for Silverlight, you can create a Visual Basic implementation of the control alternatively.
Here’s the VB.NET implementation of the control:
Imports System.Windows.Controls.Primitives
Public Class HighlightingTextBlock
Inherits Control
' Contants
' --------
Private Const TextBlockName As String = "Text"
' Private fields
' --------------
Private Inlines As List(Of Inline)
Private TextBlock As TextBlock
' Dependency properties
' ---------------------
'
' HighlightBrush
'
Public Shared ReadOnly HighlightBrushProperty As DependencyProperty = DependencyProperty.Register("HighlightBrush", GetType(Brush), GetType(HighlightingTextBlock), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf HighlightingTextBlock.OnHighlightBrushPropertyChanged)))
Public Property HighlightBrush() As Brush
Get
Return TryCast(MyBase.GetValue(HighlightingTextBlock.HighlightBrushProperty), Brush)
End Get
Set(ByVal value As Brush)
MyBase.SetValue(HighlightingTextBlock.HighlightBrushProperty, value)
End Set
End Property
Private Shared Sub OnHighlightBrushPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
TryCast(d, HighlightingTextBlock).ApplyHighlighting()
End Sub
'
' HighlightFontWeight
'
Public Shared ReadOnly HighlightFontWeightProperty As DependencyProperty = DependencyProperty.Register("HighlightFontWeight", GetType(FontWeight), GetType(HighlightingTextBlock), New PropertyMetadata(FontWeights.Normal, New PropertyChangedCallback(AddressOf HighlightingTextBlock.OnHighlightFontWeightPropertyChanged)))
Public Property HighlightFontWeight() As FontWeight
Get
Return DirectCast(MyBase.GetValue(HighlightingTextBlock.HighlightFontWeightProperty), FontWeight)
End Get
Set(ByVal value As FontWeight)
MyBase.SetValue(HighlightingTextBlock.HighlightFontWeightProperty, value)
End Set
End Property
Private Shared Sub OnHighlightFontWeightPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim source As HighlightingTextBlock = TryCast(d, HighlightingTextBlock)
Dim value As FontWeight = DirectCast(e.NewValue, FontWeight)
End Sub
'
' HighlightText
'
Public Shared ReadOnly HighlightTextProperty As DependencyProperty = DependencyProperty.Register("HighlightText", GetType(String), GetType(HighlightingTextBlock), New PropertyMetadata(New PropertyChangedCallback(AddressOf HighlightingTextBlock.OnHighlightTextPropertyChanged)))
Public Property HighlightText() As String
Get
Return TryCast(MyBase.GetValue(HighlightingTextBlock.HighlightTextProperty), String)
End Get
Set(ByVal value As String)
MyBase.SetValue(HighlightingTextBlock.HighlightTextProperty, value)
End Set
End Property
Private Shared Sub OnHighlightTextPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
TryCast(d, HighlightingTextBlock).ApplyHighlighting()
End Sub
'
' Text
'
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(HighlightingTextBlock), New PropertyMetadata(New PropertyChangedCallback(AddressOf HighlightingTextBlock.OnTextPropertyChanged)))
Public Property [Text]() As String
Get
Return TryCast(MyBase.GetValue(HighlightingTextBlock.TextProperty), String)
End Get
Set(ByVal value As String)
MyBase.SetValue(HighlightingTextBlock.TextProperty, value)
End Set
End Property
Private Shared Sub OnTextPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim source As HighlightingTextBlock = TryCast(d, HighlightingTextBlock)
If (Not source.TextBlock Is Nothing) Then
Do While (source.TextBlock.Inlines.Count > 0)
source.TextBlock.Inlines.RemoveAt(0)
Loop
Dim value As String = TryCast(e.NewValue, String)
source.Inlines = New List(Of Inline)
If (Not [value] Is Nothing) Then
Dim i As Integer
For i = 0 To [value].Length - 1
Dim [run] As New Run
[run].Text = value.Chars(i).ToString
Dim inline As Inline = run
source.TextBlock.Inlines.Add(inline)
source.Inlines.Add(inline)
Next i
source.ApplyHighlighting()
End If
End If
End Sub
' Initializes a new instance of the HighlightingTextBlock control
Public Sub New()
Me.DefaultStyleKey = GetType(HighlightingTextBlock)
End Sub
' Enforce the template
Private Sub OnLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.OnApplyTemplate()
End Sub
' Grab the template parts
Public Overrides Sub OnApplyTemplate()
MyBase.OnApplyTemplate()
Me.TextBlock = TryCast(MyBase.GetTemplateChild(TextBlockName), TextBlock)
Dim text As String = Me.Text
Me.Text = Nothing
Me.Text = [text]
End Sub
' Update highlighting using a simple walking algorithm
Private Sub ApplyHighlighting()
If (Not Me.Inlines Is Nothing) Then
Dim text As String = IIf(Me.Text <> Nothing, Me.Text, String.Empty)
Dim highlight As String = IIf(Me.HighlightText <> Nothing, Me.HighlightText, String.Empty)
Dim compare As StringComparison = StringComparison.OrdinalIgnoreCase
Dim cur As Integer = 0
Do While (cur < [text].Length)
Dim i As Integer = IIf((highlight.Length = 0), -1, [text].IndexOf(highlight, cur, [compare]))
i = IIf((i < 0), [text].Length, i)
Do While ((cur < i) AndAlso (cur < [text].Length))
Me.Inlines.Item(cur).Foreground = MyBase.Foreground
Me.Inlines.Item(cur).FontWeight = MyBase.FontWeight
cur += 1
Loop
Dim start As Integer = cur
Do While ((cur < (start + highlight.Length)) AndAlso (cur < [text].Length))
Me.Inlines.Item(cur).Foreground = Me.HighlightBrush
Me.Inlines.Item(cur).FontWeight = Me.HighlightFontWeight
cur += 1
Loop
Loop
End If
End Sub
End Class
Nice. What about C#?
@Sergey,
The C# version was posted right before this: http://www.jeff.wilcox.name/2009/08/sl3-highlighting-text-block/