[C#] StringFormat詳解之文本方向、對齊
- 2020 年 5 月 13 日
- 筆記
- .Net CF, c#, DrawString, GDI, GDI+, StringAlignment, StringFormat, StringFormatFlags
在使用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