A Silverlight HighlightingTextBlock implemented in Visual Basic
August 26, 2009
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