사용할 수있는 내 동일 question 서로 다른 답변입니다 HollowTextBlock
:
<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>
업데이트 :
올바른 측정 기능, 일반적인 텍스트 속성에 대한 속성 값 상속 및 할당 된 공간에 텍스트를 세로로 가운데에 맞출 수있는 새로운 VerticalTextAlignment
속성이있는 HollowTextBlock
의 버전이 더 있습니다.
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 매우 멋지다! 나는 그것을 시험해 보았지만 작동한다. :) 그러나이 솔루션은 또한 마치 내 것처럼 조금은 "해킹"을 느낀다. 그리고 프레임 워크에 내장 된 뭔가가 있었으면 좋겠다. InvertOpacityMask = "True"'또는 이제는 그런 기능이 없다는 것을 알고 있습니다. 누군가이 문제를 해결할 수있는 방법이 없다면, 며칠 후에 이것을 받아 들일 것입니다. 감사합니다. –