Перенос слов для метки в 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.