[C#] StringFormat详解之文本方向、对齐

在使用GDI方式处理文本时,往往会用到StringFormat。里面的某些点有点反直觉,不够直观,所以本篇就通过图文的方式去讲解一下。

本篇内容仅涉及到文本方向、对齐的相关内容。

如有错误、不妥之处,欢迎大家指正。

一、相关属性

与文本方向、对齐相关的属性,主要与三个属性有关:

Alignment、LineAlignment、FormatFlags。

Alignment与LineAlignment的属性值都是StringAlignment枚举。StringAlignment枚举有三个成员:Near、Center、Far。其MSDN解释如下:

FormatFlags的属性值是StringFormatFlags枚举。主要与其枚举的两个成员——DirectionRightToLeft、DirectionVertical——有关。其MSDN解释如下:

二、使用搭配

1,现代文的阅读顺序:水平方向上从左到右、从上到下。

此时,FormatFlags不包含成员DirectionRightToLeft、DirectionVertical。

1.1,对于Alignment,其示意图如下:

此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

Near:左对齐

Center:居中对齐

Far:右对齐

 

1.2,对于LineAlignment,其示意图如下:

此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

Near:文本段落处于显示区域顶部

Center:文本段落处于显示区域中部

Far:文本段落处理显示区域底部

 

1.3,Alignment和LineAlignment的组合共有9种,如下所示:

 

 

2,古文的阅读顺序:垂直方向上从上到下、从右到左。 

此时,FormatFlags同时包含成员DirectionRightToLeft、DirectionVertical。

2.1,对于Alignment,其示意图如下:

此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

Near:顶部对齐

Center:居中对齐

Far:底部对齐

 

2.2,对于LineAlignment,其示意图如下:

此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

Near:文本段落处于显示区域右侧

Center:文本段落处于显示区域中侧

Far:文本段落处理显示区域左侧

 

2.3,Alignment和LineAlignment的组合共有9种,如下所示:

 

 

3,其他

除上文两种搭配方式之外,还有两种搭配方式,即分别使用DirectionRightToLeft和DirectionVertical,这两种搭配方式共有18种样式,不过日常几乎用不到。具体想查看可以通过文末提供的示例源代码自行查看。

 示例程序截图:

 

三、重点说明

仅搭配使用而言,并没有什么可多说的,直接使用即可,但是如果想在某个具体的区域内显示文本段落的话——比如上面的示例截图,其坐标的计算是个难点。

这里的“坐标”并不是人眼看上去的坐标,而是使用Graphics.DrawString时所使用的坐标——绘制文本的左上角。

下面进行举例说明。

 

例1,现代文方式、右对齐、居中显示。

 示意图如下所示(这个示意图是用GDI画的,其中绿框是后期为了方便讲解而手动加的):

其中:

显示区域(上图的蓝色方框):宽=高=200

文本区域:即字符串所占的矩形区域(上图中绿色方框):宽:165,高:43

此时,在使用DrawString时,其point(绘制文本的左上角)的坐标并不是绿色方框的左上角:X:200-165=35,Y:(200-43)/2=78(此处取整数)

其坐标应该是:X:200,Y:200/2=100,即下图中红点所在的坐标(其中黄线是中线):

是不是很反直觉?

不过当接受了这种坐标计算思路之后,一切就迎刃而解了。

 

下面再举一个例子:

例2:古文方式、底部对齐、左侧显示

示意图如下所示(这个示意图是用GDI画的,其中绿框是后期为了方便讲解而手动加的):

其中:

显示区域(上图的蓝色方框):宽=高=200

文本区域:即字符串所占的矩形区域(上图中绿色方框):宽:43,高:165

此时,在使用DrawString时,其point(绘制文本的左上角)的坐标并不是绿色方框的左上角:X:0,Y:200-165=35

其坐标应该是:X:0,Y:200,即下图中红点所在的坐标:

 

四、坐标计算核心代码

完整代码见下方提供的源工程。

  1 //……
  2 
  3 Bitmap bmpStr = new Bitmap(200,200);
  4 PointF stringStart = new PointF(0, 0);
  5 
  6 if (!DirectionRightToLeft)
  7 {
  8     if (!DirectionVertical)
  9     {
 10         if (alignment == StringAlignment.Near)
 11         {
 12             stringStart.X = 0;
 13         }
 14         else if (alignment == StringAlignment.Center)
 15         {
 16             stringStart.X = bmpStr.Width / 2;
 17         }
 18         else if (alignment == StringAlignment.Far)
 19         {
 20             stringStart.X = bmpStr.Width;
 21         }
 22 
 23         if (lineAlignment == StringAlignment.Near)
 24         {
 25             stringStart.Y = 0;
 26         }
 27         else if (lineAlignment == StringAlignment.Center)
 28         {
 29             stringStart.Y = bmpStr.Height / 2;
 30         }
 31         else if (lineAlignment == StringAlignment.Far)
 32         {
 33             stringStart.Y = bmpStr.Height;
 34         }
 35     }
 36     else
 37     {
 38         if (alignment == StringAlignment.Near)
 39         {
 40             stringStart.Y = 0;
 41         }
 42         else if (alignment == StringAlignment.Center)
 43         {
 44             stringStart.Y = bmpStr.Height / 2;
 45         }
 46         else if (alignment == StringAlignment.Far)
 47         {
 48             stringStart.Y = bmpStr.Height;
 49         }
 50 
 51         if (lineAlignment == StringAlignment.Near)
 52         {
 53             stringStart.X = 0;
 54         }
 55         else if (lineAlignment == StringAlignment.Center)
 56         {
 57             stringStart.X = bmpStr.Width / 2;
 58         }
 59         else if (lineAlignment == StringAlignment.Far)
 60         {
 61             stringStart.X = bmpStr.Width;
 62         }
 63     }
 64 }
 65 else
 66 {
 67     if (!DirectionVertical)
 68     {
 69         if (alignment == StringAlignment.Near)
 70         {
 71             stringStart.X = bmpStr.Width;
 72         }
 73         else if (alignment == StringAlignment.Center)
 74         {
 75             stringStart.X = bmpStr.Width / 2;
 76         }
 77         else if (alignment == StringAlignment.Far)
 78         {
 79             stringStart.X = 0;
 80         }
 81 
 82         if (lineAlignment == StringAlignment.Near)
 83         {
 84             stringStart.Y = 0;
 85         }
 86         else if (lineAlignment == StringAlignment.Center)
 87         {
 88             stringStart.Y = bmpStr.Height / 2;
 89         }
 90         else if (lineAlignment == StringAlignment.Far)
 91         {
 92             stringStart.Y = bmpStr.Height;
 93         }
 94     }
 95     else
 96     {
 97         if (alignment == StringAlignment.Near)
 98         {
 99             stringStart.Y = 0;
100         }
101         else if (alignment == StringAlignment.Center)
102         {
103             stringStart.Y = bmpStr.Height / 2;
104         }
105         else if (alignment == StringAlignment.Far)
106         {
107             stringStart.Y = bmpStr.Height;
108         }
109 
110         if (lineAlignment == StringAlignment.Near)
111         {
112             stringStart.X = bmpStr.Width;
113         }
114         else if (lineAlignment == StringAlignment.Center)
115         {
116             stringStart.X = bmpStr.Width / 2;
117         }
118         else if (lineAlignment == StringAlignment.Far)
119         {
120             stringStart.X = 0;
121         }
122     }
123 }
124 
125 //……
126 
127 g.DrawString(str, font, new SolidBrush(Color.Red), stringStart, stringFormat);
128 
129 //……

坐标计算

 

五、示例程序源代码下载

源工程文件:

 //files.cnblogs.com/files/lesliexin/StringFormat.7z