Перенос слов для метки в Windows Forms


184

Как можно получить функциональность переноса слов Labelдля текста, который выходит за пределы?

Ответы:


167

Быстрый ответ: выключите AutoSize .

Большая проблема здесь в том, что метка не изменит свою высоту автоматически (только ширина). Чтобы сделать это правильно, вам нужно будет создать подкласс метки и включить логику вертикального изменения размера.

В основном, что вам нужно сделать в OnPaint:

  1. Измерьте высоту текста (Graphics.MeasureString).
  2. Если высота надписи не равна высоте текста, установите высоту и вернитесь.
  3. Нарисуй текст.

Вам также нужно будет установить флаг стиля ResizeRedraw в конструкторе.


12
Выберите метку, к которой вы динамически добавляете текст. Посмотрите на свойства метки и выключите AutoSize. Теперь вы сможете перетаскивать / устанавливать область для метки, и она автоматически будет переноситься в соответствии с этими параметрами. Нет необходимости в каком-либо дополнительном кодировании.
— madeFromCode

Это именно то, что я искал, поскольку это касается форматирования моей формы с пояснительным текстом в форме абзаца.
— Филипп Брэк,

1
@madeFromCode Вам нужно установить высоту программно, если вы хотите, чтобы метка расширялась по вертикали, иначе ваш текст будет обрезан.
— Эдвин

348

На самом деле, принятый ответ излишне сложен.

Если вы установите метку в AutoSize, она будет автоматически расти вместе с тем текстом, который вы в нее поместите. (Это включает вертикальный рост.)

Если вы хотите сделать перенос слов определенной ширины, вы можете установить свойство MaximumSize.

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

Проверено и работает.


10
Если у вас есть метка, привязанная к ее контейнеру, вы можете отключить AutoSize, оставить свойство максимального размера как есть, и оно будет переносить слова точно так, как мы хотим. ПОЦЕЛУЙ на работе!
— TheBlastOne

Вы не можете достичь ширины жидкости с этим решением.
— Робин

1
@ Сэм: Да, вы можете просто установить правильные свойства привязки. Вы даже пробовали это?
— Джон Гитцен

1
Сэм: вы должны иметь возможность установить Dockсвойство как метки, так и панели Topвместо моего решения.
— Джон Гитцен

2
Я вцепился OnResizeв родителя и позвонилmyLabel.MaximumSize = new Size(Bounds.Width, 0);
— Крис Морган

23

В моем случае (метка на панели) я установил label.AutoSize = falseи label.Dock = Fill. И текст метки оборачивается автоматически.


Это заставляет метку заполнять всю форму и скрывать все остальные элементы управления в форме ... То есть она не работает. Существуют ли другие требования, которые не заполнили бы всю форму?
— Питер Мортенсен

5
ярлык находится на панели , а не на форме напрямую. Поэтому текст не выходит за пределы панели
— alex555

Хорошо, но разве это не заслонит все остальные элементы управления на панели?
— Питер Мортенсен

1
Что мешает вам создать дополнительную панель, содержащую только ярлык?
— alex555

Это похоже на какой-то дополнительный макет, который должен быть ненужным. Конечно, этикетка должна иметь свою собственную коробку, а не помещать ее в другую коробку.
— Эдвин

17

Свойство autowrap отсутствует, но это можно сделать программно для его динамического определения размера. Вот одно из решений:

  • Выберите свойства метки

  • AutoSize знак равно True

  • MaximumSize= ( Ширина , высота ) где ширина = максимальный размер метки, а высота = количество пикселей, которое нужно обернуть

    Свойства образца


4
Еще одно примечание: если вы оставите максимальную высоту равной 0, она будет продолжать расширяться по вертикали.
— бледная лошадь

У моего ярлыка нет свойств 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.
— Охад Шнайдер

1
Кроме того, не забудьте включить верхний и нижний отступы метки в расчет ( Height = sz.Height + Padding.Vertical;)
— Игорь Брейц

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?
— Стелс Раввин

Они сделаны в конструкторе (но могут быть выполнены в коде, если вам это нужно), и нет причин для заказа.
— noelicus

1

Не уверен , что это будет соответствовать все примеры использования , но я часто использую простой трюк , чтобы получить поведение оберточной: положить ваши Labelс AutoSize=falseвнутри 1x1 , TableLayoutPanelкоторый будет заботиться о Labelразмере «s.



0

Если ваша панель ограничивает ширину вашей метки, вы можете установить свойство привязки вашей метки влево, вправо и установить для AutoSize значение true. Концептуально это похоже на прослушивание SizeChangedсобытия Panel и обновление MaximumSize метки до a, new Size(((Control)sender).Size.Width, 0)как было предложено в предыдущем ответе. . Каждая сторона, указанная в свойстве Anchor, хорошо привязана к соответствующей внутренней стороне содержащего элемента управления. Таким образом, перечисление двух противоположных сторон в 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 во всплывающем окне, чтобы добавить строки и ввести текст, как в блокноте! (НАЖМИТЕ ВВОД, ГДЕ ВЫ ХОТИТЕ ЗАВЕРШИТЬ ЛЕЙБЛ ТЕКСТ)

-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
Голосовать за это нормально, но хотя бы скажи, почему ты это сделал. Причина, по которой это было отклонено, заключается в том, что <asp: Label> не используется в WinForms. Этот ответ для неправильной платформы.
— TheJerm

4
потому что это asp.net не winform
— Trikaldarshi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.