können Sie meine verwenden HollowTextBlock
die unterschiedliche Antwort auf die gleiche question ist:
<Grid Background="Blue">
<Border Width="100" Height="60" BorderBrush="Black" BorderThickness="2">
<Border Background="Red">
<Border.OpacityMask>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<local:HollowTextBlock Width="200" Height="50" Text="Text" Background="White" HorizontalAlignment="Center"/>
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
</Border>
</Border>
</Grid>
Update:
Hier ist eine ausgefeiltere Version von HollowTextBlock
mit geeigneter Messfunktionalität, Vererbung von Eigenschaftswerten für die üblichen Texteigenschaften und einer neuen Eigenschaft VerticalTextAlignment
für die vertikale Zentrierung des Texts in seinem zugewiesenen Bereich:
public class HollowTextBlock : FrameworkElement
{
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(HollowTextBlock), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(HollowTextBlock.OnTextChanged), new CoerceValueCallback(HollowTextBlock.CoerceText)));
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
public static readonly DependencyProperty BackgroundProperty =
TextElement.BackgroundProperty.AddOwner(typeof(HollowTextBlock), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
public double FontSize
{
get { return (double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
public static readonly DependencyProperty FontSizeProperty =
TextElement.FontSizeProperty.AddOwner(typeof(HollowTextBlock));
public FontFamily FontFamily
{
get { return (FontFamily)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
public static readonly DependencyProperty FontFamilyProperty =
TextElement.FontFamilyProperty.AddOwner(typeof(HollowTextBlock));
public FontStyle FontStyle
{
get { return (FontStyle)GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
public static readonly DependencyProperty FontStyleProperty =
TextElement.FontStyleProperty.AddOwner(typeof(HollowTextBlock));
public FontWeight FontWeight
{
get { return (FontWeight)GetValue(FontWeightProperty); }
set { SetValue(FontWeightProperty, value); }
}
public static readonly DependencyProperty FontWeightProperty =
TextElement.FontWeightProperty.AddOwner(typeof(HollowTextBlock));
public FontStretch FontStretch
{
get { return (FontStretch)GetValue(FontStretchProperty); }
set { SetValue(FontStretchProperty, value); }
}
public static readonly DependencyProperty FontStretchProperty =
TextElement.FontStretchProperty.AddOwner(typeof(HollowTextBlock));
public TextAlignment TextAlignment
{
get { return (TextAlignment)GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
public static readonly DependencyProperty TextAlignmentProperty =
Block.TextAlignmentProperty.AddOwner(typeof(HollowTextBlock));
public VerticalAlignment VerticalTextAlignment
{
get { return (VerticalAlignment)GetValue(VerticalTextAlignmentProperty); }
set { SetValue(VerticalTextAlignmentProperty, value); }
}
public static readonly DependencyProperty VerticalTextAlignmentProperty =
DependencyProperty.Register("VerticalTextAlignment", typeof(VerticalAlignment), typeof(HollowTextBlock), new FrameworkPropertyMetadata(VerticalAlignment.Top, FrameworkPropertyMetadataOptions.AffectsRender));
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
OnTextChanged(d, (string)e.NewValue);
}
private static void OnTextChanged(DependencyObject d, string newText)
{
}
private static object CoerceText(DependencyObject d, object baseValue)
{
return baseValue;
}
protected override Size MeasureOverride(Size availableSize)
{
var face = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
var size = FontSize;
var ft = new FormattedText(Text, Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, face, size, Brushes.Black);
return new Size(ft.Width, ft.Height);
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
var extent = new RectangleGeometry(new Rect(0.0, 0.0, RenderSize.Width, RenderSize.Height));
var face = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
var size = FontSize;
var ft = new FormattedText(Text, Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, face, size, Brushes.Black);
var originX = GetHorizontalOrigin(ft.Width, RenderSize.Width);
var originY = GetVerticalOrigin(ft.Height, RenderSize.Height);
var hole = ft.BuildGeometry(new Point(originX, originY));
var combined = new CombinedGeometry(GeometryCombineMode.Exclude, extent, hole);
drawingContext.PushClip(combined);
drawingContext.DrawRectangle(Background, null, new Rect(0.0, 0.0, RenderSize.Width, RenderSize.Height));
drawingContext.Pop();
}
private double GetHorizontalOrigin(double textWidth, double renderWidth)
{
switch (TextAlignment)
{
case TextAlignment.Center:
return (renderWidth - textWidth)/2;
case TextAlignment.Left:
return 0;
case TextAlignment.Right:
return renderWidth - textWidth;
}
return 0;
}
private double GetVerticalOrigin(double textHeight, double renderHeight)
{
switch (VerticalTextAlignment)
{
case VerticalAlignment.Center:
return (renderHeight - textHeight)/2;
case VerticalAlignment.Top:
return 0;
case VerticalAlignment.Bottom:
return renderHeight - textHeight;
}
return 0;
}
}
+1, sehr cool! Ich habe es ausprobiert und es funktioniert :) Aber diese Lösung fühlt sich auch ein wenig "hacky" genau wie meine und ich wünschte, es wäre etwas in das Framework eingebaut, das es Ihnen erlauben würde, einfach "InvertOpacityMask =" True "' oder Nun, ich weiß, dass es kein solches Feature gibt und wenn jemand eine Möglichkeit hat, zu arbeiten, werde ich das in ein paar Tagen als akzeptiert markieren –