英文:
How can I apply stroke to a textbox in WPF?
问题
需要对文本框应用描边(文本周围的轮廓)。
我已经尝试了一些解决方案:
- 编辑文本框的模板,使用 OutlinedTextblock(一种用于绘制带轮廓文本的自定义控件),但无法选择字符;
- 应用着色效果,但效果不佳,描边看起来很难看。
您有没有什么好的解决方案?
英文:
I need to apply stroke (outline around text) to a textbox.
I have tried some solutions:
- Edit the template of a textbox, using OutlinedTextblock (a custom control to draw the outlined text), but I can't select characters;
- apply shader effect, but it didn't work well. The stroke looked ugly.
Do you have any good solution?
答案1
得分: 1
我进行了一些实验和概念验证。
结果不算太糟,但需要进行一些改进。
当我选择文本时,蓝色区域的位置不太准确。
这是使用我在评论中提到的方法。
文本框中的文本是透明的,控件的背景用于显示格式化的文本。
我的窗口中只有这个:
<Grid>
<TextBox Width="200" Height="40"
VerticalAlignment="Top"
TextChanged="TextBox_TextChanged"
Foreground="Transparent"
FontSize="32"
>
<TextBox.Background>
<DrawingBrush Stretch="None"
AlignmentX="Left">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="LightBlue"
x:Name="TextGeometryDrawing"
Geometry="{x:Null}"
>
<GeometryDrawing.Pen>
<Pen Thickness="1" Brush="Red"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</TextBox.Background>
</TextBox>
</Grid>
我的TextChange处理程序创建几何图形:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox tb = (TextBox)sender;
FormattedText formattedText = new FormattedText(tb.Text, CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight, new Typeface("Segoe UI"), 32, Brushes.Black,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
Geometry geom = formattedText.BuildGeometry(new System.Windows.Point(0, 0));
TextGeometryDrawing.Geometry = geom;
}
看起来像这样:
另一种方法是我在地图和场景编辑器中使用的方法。我为字母a-z创建了几何图形,然后使用水平的itemscontrol,每个字母都有一个路径,使用这些几何图形。
然后,您可以精确控制每个字母。如果您不喜欢TrueType转换得到的某些方面,您可以在Inkscape中进行编辑。
然而,插入点和选择可能会更偏移。
英文:
I did a bit of experimentation and a proof of concept.
The result isn't too bad but needs a bit of work.
When I select text the blue area isn't in exactly the right place.
This works using the approach I mentioned in comments.
The text in the textbox is transparent and the background of the control is used to show the formatted text.
My windows just has this in it:
<Grid>
<TextBox Width="200" Height="40"
VerticalAlignment="Top"
TextChanged="TextBox_TextChanged"
Foreground="Transparent"
FontSize="32"
>
<TextBox.Background>
<DrawingBrush Stretch="None"
AlignmentX="Left">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="LightBlue"
x:Name="TextGeometryDrawing"
Geometry="{x:Null}"
>
<GeometryDrawing.Pen>
<Pen Thickness="1" Brush="Red"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</TextBox.Background>
</TextBox>
</Grid>
My textchanged handler creates the geometry:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox tb = (TextBox)sender;
FormattedText formattedText = new FormattedText(tb.Text, CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight, new Typeface("Segoe UI"), 32, Brushes.Black,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
Geometry geom = formattedText.BuildGeometry(new System.Windows.Point(0, 0));
TextGeometryDrawing.Geometry = geom;
}
Looks like
An alternative is the approach I use in our map and scenario editors. I create a geometry per letter a-z and then use a horizontal itemscontrol with a path per letter using those geometries.
You can then control each letter precisely. If you don't like some aspect of what you get from truetype conversion you can edit it in inkscape.
The insertion point and selection is likely to get even more offset that way though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论