Вот решение, которое работает путем создания нового FrameworkElement
под названием HollowTextBlock
, который заполняет его размер выделенного с его Background
и скрепок прочь от Text
оставляя его прозрачным. Полноценная реализация потребует поддержки гораздо большего количества свойств, но это доказывает, что концепция работает.
Во-первых, здесь приведен пример XAML:
<Grid>
<Grid>
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="#FF0000" Offset="0" />
<GradientStop Color="#0000FF" Offset="1" />
</LinearGradientBrush>
</Grid.Background>
</Grid>
<Grid>
<local:HollowTextBlock Width="200" Height="50" Text="Hello, world!" Background="White" HorizontalAlignment="Center"/>
</Grid>
</Grid>
который определяет красочный фон градиент позади текста таким образом, мы можем видеть, что это работает. Затем создадим наш HollowTextBlock
и в прототипе Width
, Height
, Text
и Background
все должны быть указаны.
Тогда вот наша реализация 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 UIPropertyMetadata(string.Empty));
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));
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("Arial");
var size = 32;
var ft = new FormattedText(Text, Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, face, size, Brushes.Black);
var hole = ft.BuildGeometry(new Point((RenderSize.Width - ft.Width)/2, (RenderSize.Height - ft.Height)/2));
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();
}
}
и просчитанный результат выглядит следующим образом:
нотабене Когда вы используете его, вы должны быть осторожны, чтобы не поставить его поверх чего-то, что затмило бы реальный фон, который вы хотели бы показать.
Я не совсем понимаю, что вы пытаетесь сделать. Не могли бы вы опубликовать скриншот или какой-нибудь пример кода? –
Спасибо за ваш ответ ... Я бросил это вместе в фотошопе и надеюсь, что это поможет ... http://users.indytel.com/~jsmain/downloads/NowPlaying.png. Я хочу увидеть фон через серебряную границу, а также тени эффект границы, как на этом изображении. Я не могу понять, как исключить геометрию текста из границы в xaml. –