今天来聊聊我捣鼓MeasureString
这玩意儿的经历。
起因是这样的,我当时在做一个界面,需要在某个区域里头显示一段文字,而且要求得挺严格,必须得居中,或者说,得确保这文字不能超出给定的那个框框。
一开始我脑子简单,想着直接拿字符串的Length
属性不就行?结果试一下,立马发现不对劲。这Length
返回的是字符个数,比如"iii"和"WWW",个数一样,但在屏幕上占的宽度那可差远去。一个字母 i 很窄,一个字母 W 就很宽。所以光知道字符数,根本没法确定它到底有多宽,占多少像素。
摸索过程
没办法,只能找找有没有别的法子。我就开始琢磨,怎么才能知道一段文字真正显示出来的时候,它到底占多大的地方,具体是多少像素宽、多少像素高?
搜寻一番,找到一个叫MeasureString
的方法。看名字就觉得靠谱,“测量字符串”,这不就是我想要的吗?看看说明,它是跟图形绘制(Graphics
对象)相关的。
动手实践
正好我当时也是在处理绘图相关的逻辑,手头就有个Graphics
对象。于是我就试着用一下。
用法大概是这样:
- 你得先有个
Graphics
对象,就是你要画图的那块画布。 - 然后是你想要测量的那段文字。
- 是你打算用什么字体、多大字号来显示这段文字,也就是个
Font
对象。
我把这三样东西传给MeasureString
方法,像这样:graphics对象.MeasureString("我要测量的文字", 我的字体)
。
调用完之后,它返回给我一个东西,类型是SizeF
。我看下,这SizeF
里面就包含两个值:一个Width
和一个Height
。这不就是我苦苦寻找的,文字实际渲染出来的宽度和高度嘛单位还是像素!
解决问题
拿到这个SizeF
之后,事情就好办多。
比如要居中显示:
我知道容器的宽度,也知道文字的宽度(),那文字开始绘制的 X 坐标不就是 (容器宽度 - 文字宽度) / 2
嘛同样的方法计算 Y 坐标,用容器高度和文字高度()就行。
比如要判断文字是否会超出边界:
直接比较是不是小于等于容器的可用宽度,是不是小于等于容器的可用高度,就能知道文字放不放得下。
一点小发现
后来用着用着,也发现一些要注意的地方。比如,有的时候,你把一个长字符串拆成单个字符,分别去测量每个字符的尺寸,再把这些尺寸加起来,得到的结果可能跟直接测量整个长字符串得到的结果不太一样。
我猜这可能跟字符间距或者某些特殊字符的处理方式有关。不过对于我当时的需求来说,直接测量整个字符串得到的那个整体的宽度和高度就够用,它给的是一个能框住整个字符串的矩形尺寸。
这回实践让我搞明白,当需要在界面上精确控制文字布局,特别是需要知道文字像素尺寸的时候,MeasureString
这东西是真的挺好使。过程不复杂,关键是得知道有这么个工具可以用。