C# WinForm 中Label自动换行 解决方法
From:?http://hi.baidu.com/tewuapple/blog/item/74070a2451cbcc7c36a80f76.html
在TableLayoutPannel中放著一些Label
如果把Label的AutoSize屬性設成True的話,文字超過label長度時就會自動增加,直到后面的字出窗體以外
設置成False時,一旦到達Label的長度,后面的字符也就顯示不出來了
經過我的多番實踐,最佳的解決方法是
把Label的Dock屬性設置成Fill,并同時把Label的AutoSize屬性設成False。
以上只是一種簡便的解決方法,如果以上方法解決不了問題,就老老實實計算控件大小以適應文本吧。
-----------------------------------------------------------------
具體方法:
C# WinForm中的Label,Button等控件在布局上和Web Application中不一樣。
在WebApplication中,你可以指定它們的Width屬性,然后當在指定Width內顯示不全時,就自動換行,自動增加其Height 屬性。
在WinForm中系統不會替你做這些事情。系統要求你必須同時指定Width和Height屬性,缺一不可。當一行顯示完而高度不足以顯示第二行時,控件上的字符就會被截斷。后面的字符就不會被顯示出來了。
要實現WinForm中類似于WebApp的文本自動換行功能,你就必須手動編程設置控件的高度Height。在把控件添加進Form之前,應先獲得控件控件顯示文本的字數sumChar=Control.Text.Length,根據字數計算出需要多少行rowCount=(numChar/每行顯示字數)+1 (注意:因為當不滿一行時,(int)(numChar/每行顯示字數)=0,因此必須再加一),那么控件的高度就是Control.Height=rowCount*每行文本的高度
在添加控件進Form之前,加入Control.Size = new Size (控件寬度,計算出來的控件高度)
OK。
應當注意的是,由于中英文以及各種符號的寬度不一致,所以每行顯示的字數很難精確計算出來。可以根據顯示內容以及經驗,確定一個平均值,并且在完成之后多調試,最終確定一個合適的值。
-------------------------------------------------------------------------------
1.單行完全顯示:Label.AutoSize = true;
2.換行顯示:Label.?AutoSize = false;(Label框高度用戶指定)。
3.多行顯示,并且根據字數自動控制高度:Label.AutoSize = true;Label.MaximumSize = new Size(w,0); 注:w:用戶設定的寬度。
------------------------------------------------------
label自動換行的折衷方案:
核心關鍵在于利用TextBox的MultiLine自動換行功能,實現自動換行,其他就是顏色的設置、高度及所屬窗體高度的自動調整。
采用TextBox來實現文字的自動換行,textBox背景色設置為:Control色,AutoSize = true;MultiLize = true;Height = 12;
每個字符占用的寬度大約是12;
然后添加以下代碼:
?????????? int LblNum = ConfStr.Length;???????????????????????????????????????????? //TextBox內容長度
?????????? int RowNum = (int) txtBoxSp.Width/12;?????????????????????????????? //每行顯示的字數(計算出來的)
?????????? int RowHeight = 12;???????????????????????????????????????????????????????????? //每行的高度
?????????? int ColNum = (LblNum - (LblNum / RowNum) * RowNum) == 0 ? (LblNum / RowNum) : (LblNum / RowNum) + 1;?? //列數
????????????
?????????? if(ColNum == 1)
?????????? {
?????????????? this.Height = 278;?????????????????????????????????????????????????? //禁止窗體顯示textBox;
?????????????? this.AutoSize = false;
?????????? }
?????????? else
?????????? {
?????????????? txtBoxSp.AutoSize = true;???????????????????????????????????????? //設置AutoSize
?????????????? txtBoxSp.Height = RowHeight * ColNum;?????????????????? //設置顯示高度
?????????????? this.Height = 303 + txtBoxSp.Height + 6;????????????????? //實現窗體高度的自動調整
?????????? }
------------------------------------------------------
The fundamental problem in 1.1
When label is set to AutoSize = true, it measures as if all the text wants to be on one line.? In order to have multiple lines of text in 1.1, the AutoSize property cannot be used.
Guessing in 1.1
When you drop a label on a form in version 1.0/1.1 it is set to AutoSize = false.? The label can be resized to force the text onto the next line based upon the width of the control.? However, guessing the right height for the label can be problematic – if it is not created tall enough, the text will cut off at the bottom.? If it’s too tall there will be embarrassing gaps of whitespace in the dialog.? To solve this, folks typically used Graphics.MeasureString() with the width the label was currently set to, then used the resultant height to set the size of the label.?
There’s all kinds of problems with the latter approach – it doesn’t take into account several extra spacing/non-client borders of the control, it’s not good for performance (if you’re using Control.CreateGraphics() can force the label’s handle to be created before it normally would, etc). …and finally if you upgrade in 2.0 to?UseCompatibleTextRendering = false, the calculations will be wrong.
APIs to avoid Guessing in 2.0
The Label control now has a GetPreferredSize() method which takes wrapping constraints.? This method will take out all the headaches of guessing by taking into account all the details you might not know about, e.g. non-client borders/padding and the technology used to draw text.
Having your cake and eating it too: Strategies for Automatic Word Wrap in 2.0
It was difficult to get this right in previous versions of Windows Forms, as there was no concept of constraining size.? Updating label to support multiline constraints was a delicate balancing act as we did not want to break folks using 1.1.? (A 1.1 app should *just work* running on 2.0).? If using the regular layout stuff (i.e. not flow and table layout panels) the label should continue to work as before.
The easiest way of supporting multiline text just using “dock and anchor” layout engine was to honor a new property called MaximumSize. This gives the Label a constraining width by suggesting that the maximum width you can be is “xxxx”.? When a label is AutoSize = true, it takes into account its MaximumSize when calculating its PreferredSize.
The pitfall to using MaximumSize is that the size of the label is now fixed: if you want the label to increase in width as the dialog increases, you need to write code to increase the MaximumSize.? While this is not difficult, it would be better if we could write less code.
One possibility for fixing the Label’s MaximumSize quandary is to place the label in a FlowLayoutPanel.? When a FlowLayoutPanel is anchored left|right, it has a constraining width, which it passes onto the label.? Setting the FlowLayoutPanel to AutoSize = true, the FlowLayoutPanel will grow in height as the label grows. (The label actually had a constraining width as well when anchored, but for compatibility reasons chose to ignore it.)? Because the label is in a new layout container, it is free to honor the wrapping constraints without the possibility of breaking anyone.? As the dialog is resized, the FlowLayoutPanel is resized, which in-turn passes a new constraint to the label.
Now that we have the label dynamically changing height with respect to the width of the dialog, we have another problem to solve.? If there is another control directly underneath the label, the label can obscure the control directly underneath it.? We need to find a way to push the other controls down when the label grows in height.
We could add the control below it to the FlowLayoutPanel we’ve just added, but if we want finer control of the sizing relationship, the situation calls for a TableLayoutPanel.? Controlling sizing behavior in TableLayoutPanel means controlling the ColumnStyles and RowStyles.? There are three kinds of ColumnStyles and RowStyles in the TableLayoutPanel: Percentage, Absolute and AutoSize.?
Briefly: When the TableLayoutPanel control arranges its columns, it assigns priorities to each ColumnStyle in the following order:
1. Columns with ColumnStyle set to Absolute are considered first, and their fixed widths are allocated.
2. Columns with ColumnStyle set to AutoSize are sized to their contents.
3. Remaining space is divided among columns with ColumnStyle set to Percent.
By placing a label within a column that has specific a sizing behavior, the label will wrap.? When the label wraps, controls in rows below it will be pushed down if the RowStyle is set to AutoSize.
Here’s a quick table of the behavior of labels within a TableLayoutPanel (TLP) and why they behave that way.
| TLP AutoSize | TLP ColumnStyle | Will Label Wrap? | Why? |
| True and False | Absolute | Yes | Known constraints Since the column is absolute, we have a known dimension to pass to the label as a wrapping distance. |
| True and False | AutoSize | No | Unknown constraints Setting the column to AutoSize implies that we don’t understand currently what the size of the column should be.? Therefore all AutoSize = true controls are asked, “given infinite space, what size would you prefer to be?” |
| False | Percentage | Yes | Known constraints Since the table is AutoSize = false, we understand that the % style column is a percentage of the remaining space in the table.? Therefore we have a known dimension to pass to the label as a wrapping distance. |
| True | Percentage | No | Unknown constraints Since the table is AutoSize = true, we don’t understand what % should mean, as in an AutoSize = true table, there should be no free space.? In this case, the TLP reverse-engineers what the size of the column should be based on the infinite preferred size of the contents.? E.g. if a control is 50% and it says it wants to be 100px, the other 50% column should be 100px big.? |
In summary:
Use label.MaximumSize if:
If you have no controls beneath your label AND your label width will remain fixed.
Use label in an anchored, autosized FlowLayoutPanel if:
If you have no controls beneath your label AND your label width will grow as a function of the dialog width.
Use label in a TableLayoutPanel if:
You have controls beneath your label that need to be moved as a function of label text length.? You will have to play with the right balance of ColumnStyles and whether or not it is necessary to actually AutoSize the TableLayoutPanel itself.?
As a last resort:
If you still cant figure it out, set label.AutoSize = false, and set the label.Size = label.GetPreferredSize( … ) with custom text wrapping constraints.
Updates:
Labels set to FlatStyle.System never word wrap when AutoSize is set to true.? Some folks use FlatStyle.System to scoot the text over to line up with the edge of the panel.? You can change your Label.Margin.Left = 0 so it will line up with other controls with a Margin.Left = 3.?
If you want Wrapping RadioButtons and CheckBoxes?read here.
See the designer generated code for the samples!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的C# WinForm 中Label自动换行 解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 下载UltraEdit UE 破解版方法
- 下一篇: ue编辑器绿色免安装版