【啰嗦2句】
? ? ?現在用C#的人很少了吧?GDI+更少了吧?所以這個問題估計也冷門。沒關系,分享給特定需要的人也不錯。
【問題現象】? ?
? ? 工作中開發了一個報告編輯器,實現圖文排版等功能,用著沒什么問題,直到有一天發現,文本框粘貼的內容暗藏Tab鍵(保存為\t字符),比如“銀絲雞蛋面? ? ? ? GB 28050-2011? ? ? ?100克?”,用DrawString怎么繪制都會忽略中間的間距,變成“銀絲雞蛋面GB 28050-2011100克”。
? ?比較糟糕的是MySQL數據庫查看時的值也是“銀絲雞蛋面GB 28050-2011100克”。
?【分析歷程】
? ? ?剛開始并不知道是中間包含著Tab鍵,從MySQL數據庫復制到NotePad++后,發現有這個tab分隔才找到原因。還以為是沒法保存\t這個符號。
? ? 既然有這個鍵值為什么DrawString沒有識別并區分呢?不知道。CSDN的做法比較巧妙,我編輯這篇文章時,看到CSDN把Tab鍵轉換成了8個空格。這個是不錯的做法,按理說我的報告編輯器也可以這么做。但是,仍然希望所見所得吧,作為報告,希望保留內容的原始性。
? ? 最終在微軟在線文檔中發現有個StringFormat.SetTabStops()方法,似乎是一個希望。鏈接看這個:微軟文檔StringFormat.SetTabStops(Single, Single[]) 方法
? 【解決案例】
? ? 1、微軟文檔的做法,其實并沒有解決問題。
? ? 新建一個窗體Form1,雙擊Paint事件編輯代碼。
/// <summary>
/// 直接在Form的Paint演示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Paint(object sender, PaintEventArgs e)
{//注意“直接的”前面是換行符string text = "Hello, 移動中的鴨子!\n直接的\t方法\t來獲\t取每\t個字符的精確位置。";Graphics graphics = e.Graphics;// 設置文本的布局,制表符將會根據這個對齊方式計算StringFormat format = new StringFormat();format.Alignment = StringAlignment.Near;//這個tabStops是重點,但是也很難搞懂float[] tabStops = { 100.0f,50.0f,20.0f,100.0f,20.0f }; //每個間隔跟上一個的間隔像素format.SetTabStops(0, tabStops);//設置起始符位置0,其他的按tabStopsgraphics.DrawString(text, this.Font, new SolidBrush(Color.Green), 10, 10, format);
}
原文:Hello, 移動中的鴨子!\n直接的\t方法\t來獲\t取每\t個字符的精確位置
運行效果如下圖:
這里微軟官方解釋:
tabStops
?數組中的每個制表位偏移量(第一個除外)相對于上一個。 第一個制表位偏移量相對于由?firstTabOffset
指定的初始偏移位置。 例如,如果初始偏移位置為 8,第一個制表位偏移量為 50,則第一個制表位位于位置 58。 如果初始偏移位置為零,則第一個制表位偏移量相對于位置 0(字符串原點)。
實際我測試了多個tabStops數組值,第一個值比較準,其他表現得莫名其妙。比如:
tabStops = { 100.0f,50.0f,20.0f,50.0f}
? ? 由于資料很少,所以這個方案只能作為參考,可能受不同系統語言、地區等影響表現未必符合要求。有興趣的讀者可以再摸索摸索。
?2、參照CSDN這種做法,直接把\t替換為4個或8個空格。推薦用這種方法。
label3.Text = text.Replace("\t", " ");
?