我想修改 WPF TextBox 中字符之间的间距。
类似于 CSS 中可用的 letter-spacing: 5px
内容。
我认为在 XAML 中这是可能的;最简单的方法是什么?
我找到了“GlyphRun 对象和 Glyphs 元素简介”文档,并发现它毫无帮助。
这是该页面的代码示例:
<!-- "Hello World!" with explicit character widths for proportional font -->
<Glyphs
FontUri = "C:\WINDOWS\Fonts\ARIAL.TTF"
FontRenderingEmSize = "36"
UnicodeString = "Hello World!"
Indices = ",80;,80;,80;,80;,80;,80;,80;,80;,80;,80;,80"
Fill = "Maroon"
OriginX = "50"
OriginY = "225"
/>
同一文档页面对 Indices
属性的作用进行了“解释”:
我不知道这意味着什么。我也不确定索引是否正确 - 代码中的注释提到了我不关心的“字符宽度”。我想调整字符之间的宽度。
此外,也没有关于如何将 Glyphs 元素应用到 TextBox 的示例。当我尝试时,我的 WPF 测试应用程序崩溃了。
我想要做的是稍微增加 WPF 文本框中绘制的字符之间出现的空白空间。文本的长度和内容会有所不同。每次出现新字符时是否都必须修改 Indicies
属性?有没有办法说“为每个角色设置比平常多 20% 的空间”。
有人可以帮助我吗?
I'd like to modify the spacing between characters in a WPF TextBox.
Something like the letter-spacing: 5px
thing that is available in CSS.
I think it is possible in XAML; what's the simplest way?
I found the "Introduction to the GlyphRun Object and Glyphs Element" document, and found it to be exceedingly unhelpful.
This is a code example from that page:
<!-- "Hello World!" with explicit character widths for proportional font -->
<Glyphs
FontUri = "C:\WINDOWS\Fonts\ARIAL.TTF"
FontRenderingEmSize = "36"
UnicodeString = "Hello World!"
Indices = ",80;,80;,80;,80;,80;,80;,80;,80;,80;,80;,80"
Fill = "Maroon"
OriginX = "50"
OriginY = "225"
/>
The same documentation page gives this "explanation" for what the Indices
property does:
I have no idea what any of that means. I'm also not sure that Indices is the right thing - the comment in the code speaks of "character widths" which I don't care about. I want to adjust the width between characters.
Also, there is no example for how to apply a Glyphs
element to a TextBox. When I tried it, my WPF test app just crashed.
What I want to do is slightly increase the empty space that appears between drawn characters within a WPF TextBox. The text will vary in length and content. Do I have to modify the Indicies
property every time there is a new character? Is there a way to say "make it 20% more space than usual, for every character".
Can anybody help me?
发布评论
评论(5)
我尝试了 Glyphs 和 FontStretch,但无法轻松获得我想要的结果。我能够想出一种适合我的目的的方法。也许它也对其他人有用。
我可以绑定到任何字符串,并且不需要进行任何字符宽度检测来正确设置间距。右边距是字母之间的空格。
示例:
I tried Glyphs and FontStretch and couldn't easily get the result I was looking for. I was able to come up with an approach that works for my purposes. Maybe it will work for others, as well.
I can bind to any string and don't need to do any character width detection to set the spacing properly. The right margin is the space between the letters.
Example:
我找到了一种使用 TextBlock 类,因为它支持 翻译转换。通过将
TextBlock.TextProperty
上的默认PropertyChangedCallback
替换为自定义的,我们可以将TranslateTransform
应用于TextBlock< 中的每个字母/代码>。
这是我所做的完整的逐步编码:
首先,我们创建一个自定义类并继承
TextBlock
,如下所示:然后,在 XAML 中,我们将 TextBlock 更改为我们的自定义类(更多信息可以找到 此处):
最后,在
.cs
代码隐藏文件中的InitializeComponent()
方法之前,添加OverrideMetadata
方法,如下所示:...并在每次
TextProperty
更改时将TranslateTransform
应用于每个字母:NOTES :
首先,我是 WPF 和 C# 的新手,所以我的答案可能不是最干净的解决方案。如果您对如何改进这个答案有任何意见,我们将不胜感激!
其次,我还没有使用大量
TextBlock
元素测试此解决方案,并且(可能)存在巨大的性能损失,因为TranslateTransform
应用于中的每个单独字母一个TextBlock.Text
。最后,
TextBlock
的文本超出TranslateTransform
的任何正X
值的范围。我认为您可以重新计算TextBlock
的宽度,然后以编程方式放置它(?)I found a way to have letter spacing with TextBlock class as it supports TranslateTransforms. By replacing a default
PropertyChangedCallback
on theTextBlock.TextProperty
with a custom one, we can applyTranslateTransform
to each letter in theTextBlock
.Here is a complete step-by-step coding I did:
First, we create a custom class and inherit from
TextBlock
like so:Then, in XAML, we change the TextBlock to our custom class (more information can be found here):
Finally, before the
InitializeComponent()
method in the.cs
code-behind file, add theOverrideMetadata
method like so:... and apply
TranslateTransform
to each letter each timeTextProperty
changes:NOTES:
First, I am a complete novice in WPF and C#, so my answer might not be the cleanest solution available. If you have any comments on how to improve this answer, it will be greatly appreciated!
Second, I haven't tested this solution with a large number of
TextBlock
elements, and there (probably) is a huge performance penalty asTranslateTransform
is applied to each individual letter in aTextBlock.Text
.Finally, the text of the
TextBlock
goes out of bounds with any positiveX
value forTranslateTransform
. I think that you can re-calculate the width of theTextBlock
and only then place it programmatically (?)FontStretch 适合您吗?
否则,您可能需要在那里查看 this是一个图像,显示了前进宽度的含义。虽然我以前没有这样做过,也不知道这是否有效,但增加左右侧轴承可能就是您想要的!
is FontStretch an option for you?
Otherwise you might want to look into this there is an image, showing what advance width means. Though I have not done this before and don't know if this works increasing right and left side bearings might be what you want!
虽然我喜欢
ItemsControl
hack,但这里有一个简单的 Unicode "Space分隔符” 技巧可能对某些人有用。为了提高性能,您可能希望将值缓存在视图模型中,而不是使用转换器。
Though I like the
ItemsControl
hack, here's a simple Unicode "Space Separator" trick that might work for some.For performance, you might want to cache the value in the view model instead of using a converter.
它的价值是什么。 。 。
如果您可以选择将实现切换到 RichTextBox,这可能比您在 2013 年 9 月找到的解决方法更容易。我只是根据自己的需要尝试了它,它可以满足我的需要。我没有看到 RichTextBox 可以像排字机那样控制各个空间的字距调整的方法。但 TextBox 会像 HTML 一样占用额外的空间(将多个相邻空间合并为一个空间)。我需要让空格显示与文本字符串中相同的间距,而 RichTextBox 可以做到这一点。
我不是专家,但似乎您无法在 XAML 中指定文本内容。我必须在代码隐藏事件中指定它:
For what its worth . . .
If you have the option to switch your implementation to RichTextBox, this might be easier than the work-around you found Sept 2013. I just tried it for my own needs and it works for what I need. I do not see a way with RichTextBox to control kerning of individual spaces like typesetters do. But TextBox was eating additional spaces (consolidating multiple adjacent spaces to a single space) like HTML. I needed for the spaces to display the same amount of spacing as is in my text String, and RichTextBox does this.
I'm no expert, but it seems you can't specify the text content in XAML. I had to specify it in a code-behind event: