Windows窗体中标签的自动换行


183

我们如何获得Windows窗体中标签的自动换行功能?

我在面板上放置了标签,并添加了一些文本来动态标记。但是它超过了面板的长度。我该如何解决?

Answers:


165

快速答案:关闭 AutoSize

这里最大的问题是标签不会自动更改其高度(仅更改宽度)。为了实现此目的,您需要对标签进行子类化,并包括垂直调整大小逻辑。

基本上,您需要在OnPaint中执行以下操作:

  1. 测量文本的高度(Graphics.MeasureString)。
  2. 如果标签的高度不等于文本的高度,则设置高度并返回。
  3. 绘制文本。

您还需要在构造函数中设置ResizeRedraw样式标志。


12
选择您要动态添加文本的标签。查看标签的属性,然后关闭“自动调整大小”。现在,您将能够拖动/设置标签的区域,它将自动自动换行以保持在这些参数之内。无需任何其他编码。
madeFromCode 2012年

这正是我一直在寻找的内容,它涉及用段落形式的解释性文本来格式化表格。
菲利普·布拉克

1
@madeFromCode如果您希望标签垂直扩展,则需要以编程方式设置高度,否则文本将被剪切。
艾德温

348

实际上,接受的答案不必要地复杂。

如果将标签设置为“自动调整大小”,它将随输入的文本自动增长。(这包括垂直增长。)

如果要使其以特定宽度自动换行,可以设置MaximumSize属性。

myLabel.MaximumSize = new Size(100, 0);
myLabel.AutoSize = true;

经过测试和工作。


10
如果您将标签卡入容器中,则可以关闭AutoSize,将max size属性保持原样,它将完全按照我们的需要自动换行。吻在工作!
TheBlastOne

该解决方案无法实现流体宽度。
罗宾(Robin)

1
@Sam:是的,您可以设置适当的“ anchor”属性。你试过了吗?
John Gietzen 2012年

1
Sam:您应该可以Dock将label和panel 的属性都设置为Top,而不是我的解决方案。
约翰·吉森

2
我锁定OnResize了父母并打电话给我myLabel.MaximumSize = new Size(Bounds.Width, 0);
克里斯·摩根

23

就我而言(面板上的标签),我设置label.AutoSize = falselabel.Dock = Fill。标签文本将自动换行。


这会使标签填充整个表单,并使表单中的所有其他控件变得晦涩难懂……也就是说,它似乎不起作用。是否还有其他要求不能填满整个表格?
彼得·莫滕森

5
标签在面板上,而不是直接在表单上。因此,文本不会超出面板的范围
alex555

好的,但是那会不会掩盖面板中的所有其他控件?
Peter Mortensen 2014年

1
是什么使您无法创建仅包含标签的额外面板?
alex555

这似乎是一些不必要的额外布局。当然,标签应该有自己的盒子,而不必放在另一个盒子中。
艾德温

17

坏消息:没有自动包装属性。

好消息:隧道尽头有灯!

您可以通过编程来完成此操作以动态调整大小,但这是最简单的解决方案:

  • 选择标签的属性
  • AutoSize = True
  • MaximumSize =(WidthHeight),其中Width =您希望标签成为的最大尺寸,而Height =您希望包装多少像素

    样品性质


4
另外请注意,如果将最大高度保留为0,它将继续垂直扩展。
古马2014年

我的标签没有AutoSize和MaximumSize属性,如何添加这些属性?
mrbengi

11

MSDN自动在标签中换行

using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

public class GrowLabel : Label {
    private bool mGrowing;
    public GrowLabel() {
        this.AutoSize = false;
    }
    private void resizeLabel() {
        if (mGrowing) 
            return;
        try {
            mGrowing = true;
            Size sz = new Size(this.Width, Int32.MaxValue);
            sz = TextRenderer.MeasureText(this.Text, this.Font, sz, TextFormatFlags.WordBreak);
            this.Height = sz.Height;
        }
        finally {
            mGrowing = false;
        }
    }
    protected override void OnTextChanged(EventArgs e) {
        base.OnTextChanged(e);
        resizeLabel();
    }
    protected override void OnFontChanged(EventArgs e) {
        base.OnFontChanged(e);
        resizeLabel();
    }
    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);
        resizeLabel();
    }
}

为了中断字符而不是单词(当您的字符串较长且没有空格(例如文件路径)时很有用),请改用(TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl)。请参见同一MSDN线程中的最新文章。
Ohad Schneider

1
另外,别忘了在计算中包括标签的顶部和底部填充(Height = sz.Height + Padding.Vertical;
Igor Brejc 2014年

6

我必须找到一个快速的解决方案,因此我只使用了具有以下属性的TextBox:

var myLabel = new TextBox
                    {
                        Text = "xxx xxx xxx",
                        WordWrap = true,
                        AutoSize = false,
                        Enabled = false,
                        Size = new Size(60, 30),
                        BorderStyle = BorderStyle.None,
                        Multiline =  true,
                        BackColor =  container.BackColor
                    };

这是一个很好的解决方案,但是我可能更喜欢使用ReadOnly来将Enabled设置为false。
PahJoker

1
这是一个富有想象力的解决方案,也可以在Compact Framework(Label不具有AutoSize和MaximumSize属性)的情况下很好地工作。
蒂姆·库尔特

3

有一个更好的基于@hypo的答案

public class GrowLabel : Label {
    private bool mGrowing;
    public GrowLabel() {
        this.AutoSize = false;
    }
    private void resizeLabel() {
        if (mGrowing)
            return;
        try {
            mGrowing = true;
            int width = this.Parent == null ? this.Width : this.Parent.Width;

            Size sz = new Size(this.Width, Int32.MaxValue);
            sz = TextRenderer.MeasureText(this.Text, this.Font, sz, TextFormatFlags.WordBreak);
            this.Height = sz.Height + Padding.Bottom + Padding.Top;
        } finally {
            mGrowing = false;
        }
    }
    protected override void OnTextChanged(EventArgs e) {
        base.OnTextChanged(e);
        resizeLabel();
    }
    protected override void OnFontChanged(EventArgs e) {
        base.OnFontChanged(e);
        resizeLabel();
    }
    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);
        resizeLabel();
    }
}

int width = this.Parent == null ? this.Width : this.Parent.Width; 这使您可以在停靠到父面板(例如面板)时使用自动增长标签。

this.Height = sz.Height + Padding.Bottom + Padding.Top; 在这里,我们要注意顶部和底部的填充。


1
  1. 将标签放在面板内
  2. 处理ClientSizeChanged event面板的,使标签充满空间:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. 设置Auto-Size标签为true

  4. 设置Dock标签为Fill

设计人员是否已完成步骤3和4?他们为什么进入第3步和第4步?
Stealth Rabbi

它们是在设计器中完成的(但是如果需要,可以在代码中完成),没有理由下订单。
noelicus 2014年

1

不确定它是否适合所有用例,但我经常使用一个简单的技巧来获得包装行为:将您的Labelwith AutoSize=false放在1x1的内部TableLayoutPanel,这将照顾Label的大小。



0

如果面板限制了标签的宽度,则可以将标签的Anchor属性设置为Left,Right,并将AutoSize设置为true。从概念上讲,这类似于侦听Panel的SizeChanged事件并将标签的MaximumSize更新为上一个答案new Size(((Control)sender).Size.Width, 0)所建议的。锚属性中列出的每一侧都锚定到包含控件的相应内侧。因此,在Anchor中列出两个相对的面可以有效地设置控件的尺寸。左右固定可设置控件的Width属性,上下固定可设置其Height属性。

此解决方案,如C#:

label.Anchor = AnchorStyles.Left | AnchorStyles.Right;
label.AutoSize = true;

不起作用 标签增加了面板的宽度,只是它不需要包装。不幸的是,窗户没有那么宽。
ygoe

0

如果您确实希望设置独立于内容的标签宽度,那么我发现最简单的方法是:

  • 将自动调整大小设为true
  • 将最大宽度设置为所需的宽度
  • 相同地设置最小宽度

现在,标签具有恒定的宽度,但是会自动调整其高度。

然后对于动态文本,减小字体大小。如有必要,请在设置标签文本的子目录中使用此代码段:

If Me.Size.Height - (Label12.Location.Y + Label12.Height) < 20 Then
    Dim naam As String = Label12.Font.Name
    Dim size As Single = Label12.Font.SizeInPoints - 1
    Label12.Font = New Font(naam, size)
End If

0

这对我的名为InpitWindow的表单有帮助:在Designer for Label中:

AutoSize = true;
Achors = Top, Left, Right.

private void InputWindow_Shown(object sender, EventArgs e) {
    lbCaption.MaximumSize = new Size(this.ClientSize.Width - btOK.Width - btOK.Margin.Left - btOK.Margin.Right -
        lbCaption.Margin.Right - lbCaption.Margin.Left, 
        Screen.GetWorkingArea(this).Height / 2);
    this.Height = this.Height + (lbCaption.Height - btOK.Height - btCancel.Height);
    //Uncomment this line to prevent form height chage to values lower than initial height
    //this.MinimumSize = new Size(this.MinimumSize.Width, this.Height);
}
//Use this handler if you want your label change it size according to form clientsize.
private void InputWindow_ClientSizeChanged(object sender, EventArgs e) {
    lbCaption.MaximumSize = new Size(this.ClientSize.Width - btOK.Width - btOK.Margin.Left * 2 - btOK.Margin.Right * 2 -
        lbCaption.Margin.Right * 2 - lbCaption.Margin.Left * 2,
        Screen.GetWorkingArea(this).Height / 2);
}

我表格的完整代码


0

如果按钮的尺寸需要保持不变:

myButton.Text = "word\r\nwrapped"


0

如果您要事先在标签中输入文本,则可以执行此操作。

  1. 在设计器中,右键单击标签,然后单击“属性”。
  2. 在“属性”中,搜索“文本”选项卡。
  3. 单击选项卡,然后单击其旁边的箭头按钮。
  4. 将在其顶部弹出一个框。
  5. 您可以在弹出框中按Enter键以添加行并在记事本中键入内容!(在要包装标签文本的地方按Enter键)

-12

style="overflow:Scroll"在标签中使用,如以下HTML所示。这会将滚动条添加到面板内的标签中。

<asp:Label
    ID="txtAOI"
    runat="server"
    style="overflow:Scroll"
    CssClass="areatext"
    BackColor="White"
    BorderColor="Gray"
    BorderWidth="1"
    Width = "900" ></asp:Label>

3
对此进行投票是可以的,但至少要说出您这样做的原因。之所以投票否决,是因为在WinForms中未使用<asp:Label>。这个答案是针对错误的平台的。
theJerm

4
因为它是asp.net而不是winform
Trikaldarshi 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.