Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W poniższym przykładzie pokazano, jak wyświetlić tekst zastępczy w TextBox, gdy TextBox jest pusty. Gdy tekst TextBox zawiera tekst, tekst zastępczy jest ukryty. Tekst zastępczy pomaga użytkownikowi zrozumieć, jakiego typu dane wejściowe TextBox oczekuje.
W tym artykule omówiono sposób wykonywania następujących zadań:
- Utwórz dołączoną właściwość, aby podać tekst zastępczy.
- Utwórz element dekoracyjny do wyświetlania tekstu zastępczego.
- Dodaj dołączoną właściwość do kontrolki TextBox .
Tworzenie dołączonej właściwości
Za pomocą dołączonych właściwości można dołączać wartości do kontrolki. Ta funkcja jest używana dużo w WPF, na przykład podczas ustawiania Grid.Row lub Panel.ZIndex właściwości kontrolki. Aby uzyskać więcej informacji, zobacz Przegląd dołączonych właściwości. W tym przykładzie użyto dołączonych właściwości w celu dodania tekstu zastępczego do elementu TextBox.
Dodaj nową klasę do projektu o nazwie
TextBoxHelperi otwórz ją.Dodaj następujące przestrzenie nazw:
using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media;Imports System.Linq Imports System.Security.Cryptography Imports System.Windows Imports System.Windows.Controls Imports System.Windows.Documents Imports System.Windows.MediaUtwórz nową właściwość zależności o nazwie
Placeholder.Ta właściwość zależności używa delegata wywołania zwrotnego zmiany.
public static string GetPlaceholder(DependencyObject obj) => (string)obj.GetValue(PlaceholderProperty); public static void SetPlaceholder(DependencyObject obj, string value) => obj.SetValue(PlaceholderProperty, value); public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached( "Placeholder", typeof(string), typeof(TextBoxHelper), new FrameworkPropertyMetadata( defaultValue: null, propertyChangedCallback: OnPlaceholderChanged) );Public Shared Function GetPlaceholder(obj As DependencyObject) As String Return obj.GetValue(PlaceholderProperty) End Function Public Shared Sub SetPlaceholder(obj As DependencyObject, value As String) obj.SetValue(PlaceholderProperty, value) End Sub Public Shared ReadOnly PlaceholderProperty As DependencyProperty = DependencyProperty.RegisterAttached( "Placeholder", GetType(String), GetType(TextBoxHelper), New FrameworkPropertyMetadata( defaultValue:=Nothing, propertyChangedCallback:=AddressOf OnPlaceholderChanged) )Utwórz metodę
OnPlaceholderChangedw celu zintegrowania dołączonej właściwości z elementemTextBox.private static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is TextBox textBoxControl) { if (!textBoxControl.IsLoaded) { // Ensure that the events are not added multiple times textBoxControl.Loaded -= TextBoxControl_Loaded; textBoxControl.Loaded += TextBoxControl_Loaded; } textBoxControl.TextChanged -= TextBoxControl_TextChanged; textBoxControl.TextChanged += TextBoxControl_TextChanged; // If the adorner exists, invalidate it to draw the current text if (GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner)) adorner.InvalidateVisual(); } }Private Shared Sub OnPlaceholderChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs) Dim textBoxControl = TryCast(d, TextBox) If textBoxControl IsNot Nothing Then If Not textBoxControl.IsLoaded Then 'Ensure that the events are not added multiple times RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded AddHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded End If RemoveHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged AddHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged 'If the adorner exists, invalidate it to draw the current text Dim adorner As PlaceholderAdorner = Nothing If GetOrCreateAdorner(textBoxControl, adorner) Then adorner.InvalidateVisual() End If End If End SubTa metoda jest wywoływana na dwa sposoby, gdy dołączona wartość właściwości ulegnie zmianie:
- Gdy dołączona właściwość jest po raz pierwszy dodawana do
TextBox, ta metoda jest wywoływana. Ta akcja umożliwia zintegrowanie dołączonej właściwości ze zdarzeniami kontrolki. - Za każdym razem, gdy ta właściwość zostanie zmieniona, adorner może zostać unieważniony, aby odświeżyć wizualny tekst zastępczy.
Metoda zostanie utworzona w następnej sekcji
GetOrCreateAdorner.- Gdy dołączona właściwość jest po raz pierwszy dodawana do
Utwórz programy obsługi zdarzeń dla elementu
TextBox.private static void TextBoxControl_Loaded(object sender, RoutedEventArgs e) { if (sender is TextBox textBoxControl) { textBoxControl.Loaded -= TextBoxControl_Loaded; GetOrCreateAdorner(textBoxControl, out _); } } private static void TextBoxControl_TextChanged(object sender, TextChangedEventArgs e) { if (sender is TextBox textBoxControl && GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner)) { // Control has text. Hide the adorner. if (textBoxControl.Text.Length > 0) adorner.Visibility = Visibility.Hidden; // Control has no text. Show the adorner. else adorner.Visibility = Visibility.Visible; } }Private Shared Sub TextBoxControl_Loaded(sender As Object, e As RoutedEventArgs) Dim textBoxControl As TextBox = TryCast(sender, TextBox) If textBoxControl IsNot Nothing Then RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded GetOrCreateAdorner(textBoxControl, Nothing) End If End Sub Private Shared Sub TextBoxControl_TextChanged(sender As Object, e As TextChangedEventArgs) Dim textBoxControl As TextBox = TryCast(sender, TextBox) Dim adorner As PlaceholderAdorner = Nothing If textBoxControl IsNot Nothing AndAlso GetOrCreateAdorner(textBoxControl, adorner) Then If textBoxControl.Text.Length > 0 Then 'Control has text. Hide the adorner. adorner.Visibility = Visibility.Hidden Else 'Control has no text. Show the adorner. adorner.Visibility = Visibility.Visible End If End If End SubZdarzenie Loaded jest obsługiwane, aby można było utworzyć ozdobnik po zastosowaniu szablonu kontrolki. Procedura obsługi usuwa się po podniesieniu zdarzenia i utworzeniu modułu adoratora.
Zdarzenie TextChanged jest obsługiwane, aby upewnić się, że adorner jest ukryty lub wyświetlany w zależności od tego, czy dla Text ustawiono jakąś wartość.
Stwórz dekorator
Element Adorner jest wizualizacją powiązaną z kontrolką i renderowaną w obiekcie AdornerLayer. Aby uzyskać więcej informacji, zobacz Adorners Overview.
Otwórz klasę
TextBoxHelper.Dodaj następujący kod, aby utworzyć metodę
GetOrCreateAdorner.private static bool GetOrCreateAdorner(TextBox textBoxControl, out PlaceholderAdorner adorner) { // Get the adorner layer AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBoxControl); // If null, it doesn't exist or the control's template isn't loaded if (layer == null) { adorner = null; return false; } // Layer exists, try to find the adorner adorner = layer.GetAdorners(textBoxControl)?.OfType<PlaceholderAdorner>().FirstOrDefault(); // Adorner never added to control, so add it if (adorner == null) { adorner = new PlaceholderAdorner(textBoxControl); layer.Add(adorner); } return true; }Private Shared Function GetOrCreateAdorner(textBoxControl As TextBox, ByRef adorner As PlaceholderAdorner) As Boolean 'Get the adorner layer Dim layer As AdornerLayer = AdornerLayer.GetAdornerLayer(textBoxControl) 'If nothing, it doesn't exist or the control's template isn't loaded If layer Is Nothing Then adorner = Nothing Return False End If 'Layer exists, try to find the adorner adorner = layer.GetAdorners(textBoxControl)?.OfType(Of PlaceholderAdorner)().FirstOrDefault() 'Adorner never added to control, so add it If adorner Is Nothing Then adorner = New PlaceholderAdorner(textBoxControl) layer.Add(adorner) End If Return True End FunctionTa metoda zapewnia bezpieczny sposób dodawania lub pobierania elementu Adorner. Adornery wymagają dodatkowych środków bezpieczeństwa, ponieważ są dodawane do kontrolki AdornerLayer, które mogą nie istnieć. Po zastosowaniu właściwości dołączonej XAML do kontrolki, szablon kontrolki nie został jeszcze zastosowany do utworzenia drzewa wizualnego, więc warstwa zdobień nie istnieje. Po załadowaniu elementu sterującego należy pobrać warstwę zdobienia. Warstwy adornera może również brakować, jeśli do kontrolki zostanie zastosowany szablon pomijający tę warstwę.
Dodaj klasę podrzędną o nazwie
PlaceholderAdornerdoTextBoxHelperklasy.public class PlaceholderAdorner : Adorner { public PlaceholderAdorner(TextBox textBox) : base(textBox) { } protected override void OnRender(DrawingContext drawingContext) { TextBox textBoxControl = (TextBox)AdornedElement; string placeholderValue = TextBoxHelper.GetPlaceholder(textBoxControl); if (string.IsNullOrEmpty(placeholderValue)) return; // Create the formatted text object FormattedText text = new FormattedText( placeholderValue, System.Globalization.CultureInfo.CurrentCulture, textBoxControl.FlowDirection, new Typeface(textBoxControl.FontFamily, textBoxControl.FontStyle, textBoxControl.FontWeight, textBoxControl.FontStretch), textBoxControl.FontSize, SystemColors.InactiveCaptionBrush, VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip); text.MaxTextWidth = System.Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10); text.MaxTextHeight = System.Math.Max(textBoxControl.ActualHeight, 10); // Render based on padding of the control, to try and match where the textbox places text Point renderingOffset = new Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top); // Template contains the content part; adjust sizes to try and align the text if (textBoxControl.Template.FindName("PART_ContentHost", textBoxControl) is FrameworkElement part) { Point partPosition = part.TransformToAncestor(textBoxControl).Transform(new Point(0, 0)); renderingOffset.X += partPosition.X; renderingOffset.Y += partPosition.Y; text.MaxTextWidth = System.Math.Max(part.ActualWidth - renderingOffset.X, 10); text.MaxTextHeight = System.Math.Max(part.ActualHeight, 10); } // Draw the text drawingContext.DrawText(text, renderingOffset); } }Public Class PlaceholderAdorner Inherits Adorner Public Sub New(adornedElement As UIElement) MyBase.New(adornedElement) End Sub Protected Overrides Sub OnRender(drawingContext As DrawingContext) Dim textBoxControl As TextBox = DirectCast(AdornedElement, TextBox) Dim placeholderValue As String = TextBoxHelper.GetPlaceholder(textBoxControl) If String.IsNullOrEmpty(placeholderValue) Then Return End If 'Create the formatted text object Dim text As New FormattedText( placeholderValue, System.Globalization.CultureInfo.CurrentCulture, textBoxControl.FlowDirection, New Typeface(textBoxControl.FontFamily, textBoxControl.FontStyle, textBoxControl.FontWeight, textBoxControl.FontStretch), textBoxControl.FontSize, SystemColors.InactiveCaptionBrush, VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip) text.MaxTextWidth = Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10) text.MaxTextHeight = Math.Max(textBoxControl.ActualHeight, 10) 'Render based on padding of the control, to try and match where the textbox places text Dim renderingOffset As New Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top) 'Template contains the content part; adjust sizes to try and align the text Dim part As FrameworkElement = TryCast(textBoxControl.Template.FindName("PART_ContentHost", textBoxControl), FrameworkElement) If part IsNot Nothing Then Dim partPosition As Point = part.TransformToAncestor(textBoxControl).Transform(New Point(0, 0)) renderingOffset.X += partPosition.X renderingOffset.Y += partPosition.Y text.MaxTextWidth = Math.Max(part.ActualWidth - renderingOffset.X, 10) text.MaxTextHeight = Math.Max(part.ActualHeight, 10) End If ' Draw the text drawingContext.DrawText(text, renderingOffset) End Sub End ClassAdorator dziedziczy z klasy Adorner. Ten konkretny zdobnik zastępuje metodę OnRender(DrawingContext) aby narysować tekst zastępczy. Przeanalizujmy kod:
- Najpierw sprawdź, czy tekst zastępczy istnieje, wywołując metodę
TextBoxHelper.GetPlaceholder(textBoxControl). - Utwórz obiekt FormattedText. Ten obiekt zawiera wszystkie informacje o tym, jaki tekst jest rysowany na wizualizacji.
- Zarówno właściwości FormattedText.MaxTextWidth, jak i FormattedText.MaxTextHeight są ustawione na region kontrolki. Ustawiają również minimalną wartość 10, aby upewnić się, że
FormattedTextobiekt jest prawidłowy. - Element
renderingOffsetprzechowuje położenie tekstu narysowanego. - Użyj szablonu
PART_ContentHostJeśli kontrolka deklaruje go. Ta część reprezentuje miejsce, w którym tekst jest rysowany na szablonie kontrolki. Jeśli ta część zostanie znaleziona, zmodyfikuj elementrenderingOffset, aby uwzględnić jego pozycję. - Rysuj tekst przez wywołanie DrawText(FormattedText, Point), przekazanie obiektu
FormattedTextoraz pozycji tekstu.
- Najpierw sprawdź, czy tekst zastępczy istnieje, wywołując metodę
Stosowanie dołączonej właściwości
Po zdefiniowaniu dołączonej właściwości należy zaimportować jej przestrzeń nazw do kodu XAML, a następnie odwołać się do niej w kontrolce TextBox. Poniższy kod mapuje przestrzeń nazw platformy .NET DotnetDocsSample do przestrzeni nazw XML l.
<Window x:Class="DotnetDocsSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:DotnetDocsSample"
Title="Recipe Tracker" Width="400" SizeToContent="Height">
<StackPanel Margin="10">
<TextBlock FontSize="20" TextWrapping="Wrap">Welcome to Recipe Tracker! To get started, create a new account.</TextBlock>
<Label Padding="0,5">Name</Label>
<TextBox l:TextBoxHelper.Placeholder="Ex. Jeffry Goh" />
<Label Padding="0,5">Email</Label>
<TextBox l:TextBoxHelper.Placeholder="jeffry@contoso.com" />
<Label Padding="0,5">Password</Label>
<PasswordBox />
<Button HorizontalAlignment="Right" Width="100" Margin="0,10,0,5">Submit</Button>
</StackPanel>
</Window>
Dołączona właściwość jest dodawana do TextBox obiektu przy użyciu składni xmlNamespace:Class.Property.
Kompletny przykład
Poniższy kod to kompletna TextBoxHelper klasa.
public static class TextBoxHelper
{
public static string GetPlaceholder(DependencyObject obj) =>
(string)obj.GetValue(PlaceholderProperty);
public static void SetPlaceholder(DependencyObject obj, string value) =>
obj.SetValue(PlaceholderProperty, value);
public static readonly DependencyProperty PlaceholderProperty =
DependencyProperty.RegisterAttached(
"Placeholder",
typeof(string),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata(
defaultValue: null,
propertyChangedCallback: OnPlaceholderChanged)
);
private static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox textBoxControl)
{
if (!textBoxControl.IsLoaded)
{
// Ensure that the events are not added multiple times
textBoxControl.Loaded -= TextBoxControl_Loaded;
textBoxControl.Loaded += TextBoxControl_Loaded;
}
textBoxControl.TextChanged -= TextBoxControl_TextChanged;
textBoxControl.TextChanged += TextBoxControl_TextChanged;
// If the adorner exists, invalidate it to draw the current text
if (GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner))
adorner.InvalidateVisual();
}
}
private static void TextBoxControl_Loaded(object sender, RoutedEventArgs e)
{
if (sender is TextBox textBoxControl)
{
textBoxControl.Loaded -= TextBoxControl_Loaded;
GetOrCreateAdorner(textBoxControl, out _);
}
}
private static void TextBoxControl_TextChanged(object sender, TextChangedEventArgs e)
{
if (sender is TextBox textBoxControl
&& GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner))
{
// Control has text. Hide the adorner.
if (textBoxControl.Text.Length > 0)
adorner.Visibility = Visibility.Hidden;
// Control has no text. Show the adorner.
else
adorner.Visibility = Visibility.Visible;
}
}
private static bool GetOrCreateAdorner(TextBox textBoxControl, out PlaceholderAdorner adorner)
{
// Get the adorner layer
AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBoxControl);
// If null, it doesn't exist or the control's template isn't loaded
if (layer == null)
{
adorner = null;
return false;
}
// Layer exists, try to find the adorner
adorner = layer.GetAdorners(textBoxControl)?.OfType<PlaceholderAdorner>().FirstOrDefault();
// Adorner never added to control, so add it
if (adorner == null)
{
adorner = new PlaceholderAdorner(textBoxControl);
layer.Add(adorner);
}
return true;
}
public class PlaceholderAdorner : Adorner
{
public PlaceholderAdorner(TextBox textBox) : base(textBox) { }
protected override void OnRender(DrawingContext drawingContext)
{
TextBox textBoxControl = (TextBox)AdornedElement;
string placeholderValue = TextBoxHelper.GetPlaceholder(textBoxControl);
if (string.IsNullOrEmpty(placeholderValue))
return;
// Create the formatted text object
FormattedText text = new FormattedText(
placeholderValue,
System.Globalization.CultureInfo.CurrentCulture,
textBoxControl.FlowDirection,
new Typeface(textBoxControl.FontFamily,
textBoxControl.FontStyle,
textBoxControl.FontWeight,
textBoxControl.FontStretch),
textBoxControl.FontSize,
SystemColors.InactiveCaptionBrush,
VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip);
text.MaxTextWidth = System.Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10);
text.MaxTextHeight = System.Math.Max(textBoxControl.ActualHeight, 10);
// Render based on padding of the control, to try and match where the textbox places text
Point renderingOffset = new Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top);
// Template contains the content part; adjust sizes to try and align the text
if (textBoxControl.Template.FindName("PART_ContentHost", textBoxControl) is FrameworkElement part)
{
Point partPosition = part.TransformToAncestor(textBoxControl).Transform(new Point(0, 0));
renderingOffset.X += partPosition.X;
renderingOffset.Y += partPosition.Y;
text.MaxTextWidth = System.Math.Max(part.ActualWidth - renderingOffset.X, 10);
text.MaxTextHeight = System.Math.Max(part.ActualHeight, 10);
}
// Draw the text
drawingContext.DrawText(text, renderingOffset);
}
}
}
Public Class TextBoxHelper
Public Shared Function GetPlaceholder(obj As DependencyObject) As String
Return obj.GetValue(PlaceholderProperty)
End Function
Public Shared Sub SetPlaceholder(obj As DependencyObject, value As String)
obj.SetValue(PlaceholderProperty, value)
End Sub
Public Shared ReadOnly PlaceholderProperty As DependencyProperty =
DependencyProperty.RegisterAttached(
"Placeholder",
GetType(String),
GetType(TextBoxHelper),
New FrameworkPropertyMetadata(
defaultValue:=Nothing,
propertyChangedCallback:=AddressOf OnPlaceholderChanged)
)
Private Shared Sub OnPlaceholderChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim textBoxControl = TryCast(d, TextBox)
If textBoxControl IsNot Nothing Then
If Not textBoxControl.IsLoaded Then
'Ensure that the events are not added multiple times
RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded
AddHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded
End If
RemoveHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged
AddHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged
'If the adorner exists, invalidate it to draw the current text
Dim adorner As PlaceholderAdorner = Nothing
If GetOrCreateAdorner(textBoxControl, adorner) Then
adorner.InvalidateVisual()
End If
End If
End Sub
Private Shared Sub TextBoxControl_Loaded(sender As Object, e As RoutedEventArgs)
Dim textBoxControl As TextBox = TryCast(sender, TextBox)
If textBoxControl IsNot Nothing Then
RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded
GetOrCreateAdorner(textBoxControl, Nothing)
End If
End Sub
Private Shared Sub TextBoxControl_TextChanged(sender As Object, e As TextChangedEventArgs)
Dim textBoxControl As TextBox = TryCast(sender, TextBox)
Dim adorner As PlaceholderAdorner = Nothing
If textBoxControl IsNot Nothing AndAlso GetOrCreateAdorner(textBoxControl, adorner) Then
If textBoxControl.Text.Length > 0 Then
'Control has text. Hide the adorner.
adorner.Visibility = Visibility.Hidden
Else
'Control has no text. Show the adorner.
adorner.Visibility = Visibility.Visible
End If
End If
End Sub
Private Shared Function GetOrCreateAdorner(textBoxControl As TextBox, ByRef adorner As PlaceholderAdorner) As Boolean
'Get the adorner layer
Dim layer As AdornerLayer = AdornerLayer.GetAdornerLayer(textBoxControl)
'If nothing, it doesn't exist or the control's template isn't loaded
If layer Is Nothing Then
adorner = Nothing
Return False
End If
'Layer exists, try to find the adorner
adorner = layer.GetAdorners(textBoxControl)?.OfType(Of PlaceholderAdorner)().FirstOrDefault()
'Adorner never added to control, so add it
If adorner Is Nothing Then
adorner = New PlaceholderAdorner(textBoxControl)
layer.Add(adorner)
End If
Return True
End Function
Public Class PlaceholderAdorner
Inherits Adorner
Public Sub New(adornedElement As UIElement)
MyBase.New(adornedElement)
End Sub
Protected Overrides Sub OnRender(drawingContext As DrawingContext)
Dim textBoxControl As TextBox = DirectCast(AdornedElement, TextBox)
Dim placeholderValue As String = TextBoxHelper.GetPlaceholder(textBoxControl)
If String.IsNullOrEmpty(placeholderValue) Then
Return
End If
'Create the formatted text object
Dim text As New FormattedText(
placeholderValue,
System.Globalization.CultureInfo.CurrentCulture,
textBoxControl.FlowDirection,
New Typeface(textBoxControl.FontFamily,
textBoxControl.FontStyle,
textBoxControl.FontWeight,
textBoxControl.FontStretch),
textBoxControl.FontSize,
SystemColors.InactiveCaptionBrush,
VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip)
text.MaxTextWidth = Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10)
text.MaxTextHeight = Math.Max(textBoxControl.ActualHeight, 10)
'Render based on padding of the control, to try and match where the textbox places text
Dim renderingOffset As New Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top)
'Template contains the content part; adjust sizes to try and align the text
Dim part As FrameworkElement = TryCast(textBoxControl.Template.FindName("PART_ContentHost", textBoxControl), FrameworkElement)
If part IsNot Nothing Then
Dim partPosition As Point = part.TransformToAncestor(textBoxControl).Transform(New Point(0, 0))
renderingOffset.X += partPosition.X
renderingOffset.Y += partPosition.Y
text.MaxTextWidth = Math.Max(part.ActualWidth - renderingOffset.X, 10)
text.MaxTextHeight = Math.Max(part.ActualHeight, 10)
End If
' Draw the text
drawingContext.DrawText(text, renderingOffset)
End Sub
End Class
End Class
Zobacz także
.NET Desktop feedback