2012-02-12 63 views
3

我正在製作一個與Google日曆,iCalendar,Outlook日曆類似的日程安排應用程序...正如您可能已經在這些應用程序中看到的那樣,事件以矩形表示,可能非常小,特別是如果您查看整整一週。在一個矩形中包裝字,同時允許單詞被截斷

我的挑戰是在用戶點擊矩形前使用文本,爲用戶提供一個「有意義的總結」。文本應該非常緊湊。爲此,我希望它以一種不常見的方式來包裝行,但我懷疑.NET能夠在本地處理它。

如果一個單詞比矩形寬,只顯示該單詞的開頭。但是如果接下來的單詞會部分落在矩形之外,那麼在遇到空格時仍然應該發生包裝。不是每個空間都會導致下一行的換行,因爲如果有兩個或更多的單詞碰巧適合在一條很好的路線上。

我懷疑答案在於StringFormat,StringTrimming和FormatFlags的功能,但是我沒有找到完成目標的正確組合。

例如,如果我們有...

Chuck Norris 
Dentist Appointment 

由於篇幅所限,可能成爲...

Chuc 
Norr 
Denti 
Appo 

我不希望它變成:

Chuc 
k 
Norr 
is 
Dent 
ist 
Appo 
intme 
nt 

正如你在這個例子中看到的那樣,如果用戶已經知道Chuck Norris是誰,那麼字母「k」和字母「is」的存在不會幫助用戶識別名稱。事實上,這些信件的存在可能會迫使「牙醫預約」被隱藏起來,因爲垂直空間也是有限的。

我已經知道如何在以正常方式包裝的矩形中繪製文本,並且我也知道如何獲取它以避免繪製任何落在矩形之外的文本。我不知道的是如何讓它在遇到空格(或回車)時進行換行,同時防止它包裝中間單詞,如果單個單詞比矩形更寬。有什麼幫助嗎?

+0

我很驚訝還沒有答案。其實我有辦法得到我需要的結果,但我確定它比代碼密集化要求更多,並且它消耗CPU週期。也就是說,我可以循環遍歷整個字符串,反覆檢查文本部分的寬度,用CRLF的一些空格替換,然後渲染文本而不打包。如果沒有人回答這是我會做的,但是當我懷疑在.NET中已經存在的功能時,這似乎是一種浪費。 – PaulOTron2000 2012-02-15 01:49:44

回答

1

我沒有看到任何其他方式手動執行此操作。

據我所知,沒有任何標準控件按照你想要的方式工作 - 下一步就是自己實現它或者找到已經有的其他人。

也就是說,你可以對你在評論中描述的方法做一些小的改進。希望你可以把它從「有點缺憾」,以「極簡」

  • 創建從標籤繼承
  • Override the Paint event這樣就可以控制哪些內容繪製(這裏的another clear examplea more advanced one
  • 自定義控件移動只計算出現空白的字符串寬度 - 您不關心是否在畫布外畫多餘的字符,並且不會在沒有空白的情況下中斷。
  • 緩存最後一個字符串信息,只有重新計算如果發生調整大小/無效或文本更改(您需要監視相應的事件)

通過使用自定義的控制,你不改變底層Text財產 - 所以如果你想要讀出它,那就和你把它放進去一樣。這還有另一個好處,你不必記得在任何你想要的地方進行相同的轉換 - 只是重用你的控制。

如果你從一個幾乎完成你想要的控制(很有可能是標籤,除非你有其他要求)繼承,它不應該是太多的代碼/太多的處理。

如果你還沒有。你幾乎可以肯定希望有一個自定義對象反正代表一個日程表項 - 更容易閱讀,維護和對代碼,提供跨應用標準的外觀等

道歉,如果你知道這一切已經 - 因爲你不有許多SO問題/答案,難以衡量你的經驗水平。

3

嘗試使用TextRenderer.DrawText方法與TextFormatFlags.WordBreak標誌:用面板的Paint事件

例子:

Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Panel1.Paint 
    Dim sb As New StringBuilder 
    sb.AppendLine("Chuck Norris") 
    sb.AppendLine("Dentist Appointment") 

    e.Graphics.Clear(Color.White) 
    TextRenderer.DrawText(e.Graphics, sb.ToString, Panel1.Font, _ 
         Panel1.ClientRectangle, Color.Black, Color.Empty, _ 
         TextFormatFlags.WordBreak) 
End Sub 

您還可以添加TextFormatFlags.WordEllipsis加「......」去年底在矩形的邊緣被切斷的詞:

TextRenderer.DrawText(e.Graphics, sb.ToString, Panel1.Font, _ 
         Panel1.ClientRectangle, Color.Black, Color.Empty, _ 
         TextFormatFlags.WordBreak Or TextFormatFlags.WordEllipsis) 
+2

+1比我的更優雅。 – Basic 2012-02-16 00:30:40

+0

@PaulOTron2000 DrawText用DrawString修復了很多問題。看到這個答案[在.NET中繪圖文本](http://stackoverflow.com/a/7269191/719186) – LarsTech 2012-02-16 18:22:30

+0

我試過這個,雖然它確實工作,但有兩個問題。首先是當遇到CRLF時,它可能會添加一個額外的空白行。第二個是我更喜歡使用DrawString而不是DrawText,因爲它允許使用ClearType文本。 (如果你不知道,這是一種利用微妙的紅色和藍色色調提高可讀性的好技術,現在你可能會使用它,儘管除非你拍攝屏幕並放大,否則它是隱形的。) – PaulOTron2000 2012-02-16 18:23:41