Это мне очень помогло! На всякий случай, если кому-то это понадобится в будущем, вот версия VB (сделав StrokeThickness двойным и добавив свойство подчеркивания):
Imports System
Imports System.Windows.Media
Imports System.Globalization
Imports System.Windows
Imports System.Windows.Markup
Namespace CustomXaml
Public Class OutlinedText
Inherits FrameworkElement
Implements IAddChild
Private _textGeometry As Geometry
Private Shared Sub OnOutlineTextInvalidated(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
DirectCast(d, OutlinedText).CreateText()
End Sub
Protected Overrides Sub OnRender(drawingContext As System.Windows.Media.DrawingContext)
CreateText()
drawingContext.DrawGeometry(Fill, New Pen(Stroke, StrokeThickness), _textGeometry)
End Sub
Public Sub CreateText()
Dim fontStyle = FontStyles.Normal
Dim fontWeight = FontWeights.Medium
Dim fontDecoration = New TextDecorationCollection()
If Bold Then fontWeight = FontWeights.Bold
If Italic Then fontStyle = FontStyles.Italic
If Underline Then fontDecoration.Add(TextDecorations.Underline)
Dim formattedText = New FormattedText( _
Text, _
CultureInfo.GetCultureInfo("en-us"), _
FlowDirection.LeftToRight, _
New Typeface(Font, fontStyle, fontWeight, FontStretches.Normal), _
FontSize, _
Brushes.Black _
)
formattedText.SetTextDecorations(fontDecoration)
_textGeometry = formattedText.BuildGeometry(New Point(0, 0))
Me.MinWidth = formattedText.Width
Me.MinHeight = formattedText.Height
End Sub
Public Property Bold As Boolean
Get
Return CType(GetValue(BoldProperty), Boolean)
End Get
Set(value As Boolean)
SetValue(BoldProperty, value)
End Set
End Property
Public Shared ReadOnly BoldProperty As DependencyProperty = DependencyProperty.Register( _
"Bold", _
GetType(Boolean), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
False, _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property Underline As Boolean
Get
Return CType(GetValue(UnderlineProperty), Boolean)
End Get
Set(value As Boolean)
SetValue(UnderlineProperty, value)
End Set
End Property
Public Shared ReadOnly UnderlineProperty As DependencyProperty = DependencyProperty.Register( _
"Underline", _
GetType(Boolean), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
False, _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property Fill As Brush
Get
Return CType(GetValue(FillProperty), Brush)
End Get
Set(value As Brush)
SetValue(FillProperty, value)
End Set
End Property
Public Shared ReadOnly FillProperty As DependencyProperty = DependencyProperty.Register( _
"Fill", _
GetType(Brush), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
New SolidColorBrush(Colors.LightSteelBlue), _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property Font As FontFamily
Get
Return CType(GetValue(FontProperty), FontFamily)
End Get
Set(value As FontFamily)
SetValue(FontProperty, value)
End Set
End Property
Public Shared ReadOnly FontProperty As DependencyProperty = DependencyProperty.Register( _
"Font", _
GetType(FontFamily), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
New FontFamily("Arial"), _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property FontSize As Double
Get
Return CType(GetValue(FontSizeProperty), Double)
End Get
Set(value As Double)
SetValue(FontSizeProperty, value)
End Set
End Property
Public Shared ReadOnly FontSizeProperty As DependencyProperty = DependencyProperty.Register( _
"FontSize", _
GetType(Double), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
CDbl(48.0), _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property Italic As Boolean
Get
Return CType(GetValue(ItalicProperty), Boolean)
End Get
Set(value As Boolean)
SetValue(ItalicProperty, value)
End Set
End Property
Public Shared ReadOnly ItalicProperty As DependencyProperty = DependencyProperty.Register( _
"Italic", _
GetType(Boolean), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
False, _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property Stroke As Brush
Get
Return CType(GetValue(StrokeProperty), Brush)
End Get
Set(value As Brush)
SetValue(StrokeProperty, value)
End Set
End Property
Public Shared ReadOnly StrokeProperty As DependencyProperty = DependencyProperty.Register( _
"Stroke", _
GetType(Brush), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
New SolidColorBrush(Colors.Teal), _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property StrokeThickness As Double
Get
Return CType(GetValue(StrokeThicknessProperty), Double)
End Get
Set(value As Double)
SetValue(StrokeThicknessProperty, value)
End Set
End Property
Public Shared ReadOnly StrokeThicknessProperty As DependencyProperty = DependencyProperty.Register( _
"StrokeThickness", _
GetType(Double), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
CDbl(0), _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Property Text As String
Get
Return CType(GetValue(TextProperty), String)
End Get
Set(value As String)
SetValue(TextProperty, value)
End Set
End Property
Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register( _
"Text", _
GetType(String), _
GetType(OutlinedText), _
New FrameworkPropertyMetadata( _
"", _
FrameworkPropertyMetadataOptions.AffectsRender, _
New PropertyChangedCallback(AddressOf OnOutlineTextInvalidated), _
Nothing _
) _
)
Public Sub AddChild(value As Object) Implements System.Windows.Markup.IAddChild.AddChild
End Sub
Public Sub AddText(text As String) Implements System.Windows.Markup.IAddChild.AddText
Me.Text = text
End Sub
End Class
End Namespace