如何计算已知字体大小和字符的 WPF TextBlock 宽度?
假设我有 TextBlock
,其中包含文本 “Some Text” 和字体大小 10.0。
如何计算合适的 TextBlock
宽度?
Let's say I have TextBlock
with text "Some Text" and font size 10.0.
How I can calculate appropriate TextBlock
width?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用
FormattedText
类。我在代码中创建了一个辅助函数:
它返回可在 WPF 布局中使用的与设备无关的像素。
Use the
FormattedText
class.I made a helper function in my code:
It returns device-independent pixels that can be used in WPF layout.
为了记录...
我假设操作员正在尝试以编程方式确定文本块在添加到可视化树后将占用的宽度。在我看来,比 formattedText 更好的解决方案(如何处理像 textWrapping 这样的东西?)是在示例 TextBlock 上使用 Measure 和 Arrange。例如
For the record...
I'm assuming the op'er is trying to programically determine the width that the textBlock will take up after being added to the visual tree. IMO a better solution then formattedText (how do you handle something like textWrapping?) would be to use Measure and Arrange on a sample TextBlock. e.g.
提供的解决方案适用于 .Net Framework 4.5,但是,随着 Windows 10 DPI 缩放和 Framework 4.6.x 添加了不同程度的支持,用于测量文本的构造函数现在被标记为
[已过时]
,以及该方法中不包含pixelsPerDip
参数的任何构造函数。不幸的是,它有点复杂,但新的缩放功能会带来更高的准确性。
###PixelsPerDip
根据 MSDN,这代表:
这是我根据 Microsoft/WPF-Samples 具有 DPI 缩放感知功能的 GitHub 存储库。
从 Windows 10 周年版开始,需要一些额外的配置来完全支持 DPI 缩放(在代码下方),我无法正常工作,但如果没有它,这可以在配置了缩放的单个显示器上运行(并尊重缩放变化)。上述存储库中的 Word 文档是该信息的来源,因为一旦添加这些值,我的应用程序就不会启动。 此示例代码来自同一个回购协议也是一个很好的参考点。
其他要求
根据 Microsoft/WPF-Samples 上的文档,您需要向应用程序清单添加一些设置,以涵盖 Windows 10 Anniversary 在多显示器配置中每个显示器具有不同 DPI 设置的能力。可以合理地猜测,如果没有这些设置,当窗口从一个显示器移动到具有不同设置的另一个显示器时,可能不会引发 OnDpiChanged 事件,这将使您的测量继续依赖于之前的
DpiScale
。我正在编写的应用程序是为我自己编写的,我没有那种设置,所以我没有什么可测试的,当我按照指导进行操作时,我最终得到了一个由于清单而无法启动的应用程序错误,所以我放弃了,但最好检查一下并调整您的应用程序清单以包含:根据文档:
The provided solution was appropriate for .Net Framework 4.5, however, with Windows 10 DPI scaling and Framework 4.6.x adding varying degrees of support for it, the constructor used to measure text is now marked
[Obsolete]
, along with any constructors on that method that do not include thepixelsPerDip
parameter.Unfortunately, it's a little more involved, but it will result in greater accuracy with the new scaling capabilities.
###PixelsPerDip
According to MSDN, this represents:
Here's my implementation of the selected answer based on guidance from the Microsoft/WPF-Samples GitHub repository with DPI scaling awareness.
There is some additional configuration required to completely support DPI scaling as of Windows 10 Anniversary (below the code), which I couldn't get to work, but without it this works on a single monitor with scaling configured (and respects scaling changes). The Word document in the above repo is the source of that information since my application wouldn't launch once I added those values. This sample code from the same repo also served as a good reference point.
Other Requirements
According to the documentation at Microsoft/WPF-Samples, you need to add some settings to the application's manifest to cover Windows 10 Anniversary's ability to have different DPI settings per display in multiple-monitor configurations. It's a fair guess that without these settings, the OnDpiChanged event might not be raised when a window is moved from one display to another with different settings, which would make your measurements continue to rely on the previous
DpiScale
. The application I was writing was for me, alone, and I don't have that kind of a setup so I had nothing to test with and when I followed the guidance, I ended up with an app that wouldn't start due to manifest errors, so I gave up, but it'd be a good idea to look that over and adjust your app manifest to contain:According to the documentation:
我通过在后端代码中添加到元素的绑定路径解决了这个问题:
我发现这是一个比将上述引用(如 FormattedText)的所有开销添加到我的代码中更干净的解决方案。
之后,我能够做到这一点:
I resolved this by adding a binding path to the element in the backend code:
I found this to be a much cleaner solution than adding all the overhead of the above references like FormattedText to my code.
After, I was able to do this:
我发现了一些效果很好的方法......
I found some methods which work fine...
我用这个:
I use this one:
为您找到了这个:
Found this for you: