Обертання слів для мітки в Windows Forms


184

Як можна отримати функцію обгортання слів для мітки в Windows Forms ?

Я помістив мітку на панель і додав текст, щоб динамічно мітити. Але вона перевищує довжину панелі. Як я можу це вирішити?

Відповіді:


167

Швидка відповідь: вимкніть автоматичний розмір .

Велика проблема тут полягає в тому, що мітка не змінить свою висоту автоматично (лише ширина). Щоб отримати це право, вам потрібно буде підкласировать мітку та включити логіку вертикального розміру.

В основному, що вам потрібно зробити в OnPaint, це:

  1. Виміряйте висоту тексту (Graphics.MeasureString).
  2. Якщо висота мітки не дорівнює висоті тексту, встановіть висоту і поверніть.
  3. Намалюйте текст.

Вам також потрібно буде встановити прапор стилю ResizeRedraw у конструкторі.


12
Виберіть мітку, до якої динамічно додаєте текст. Подивіться на властивості етикетки та вимкніть автоматичний розмір. Тепер ви зможете перетягнути / встановити область для мітки, і вона автоматично автоматично загортається, щоб залишатися в межах цих параметрів. Не потрібно ніякого додаткового кодування.
зробленоFromCode

Це саме те, що я шукав, оскільки це стосується форматування моєї форми з пояснювальним текстом, який знаходиться у формі абзацу.
Філіп Брек

1
@madeFromCode Вам потрібно буде встановити висоту програмно, якщо ви хочете, щоб мітка розширювалася вертикально, інакше ваш текст буде вирізаний.
Едвін

348

Власне, прийнята відповідь є надмірно складним.

Якщо ви встановите мітку на AutoSize, вона автоматично зростатиме разом із текстом, який ви додаєте до неї. (Сюди входить вертикальний ріст.)

Якщо ви хочете зробити обертання слів на певну ширину, ви можете встановити властивість MaximumSize.

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

Тестується і працює.


10
Якщо у вас є контейнер з ярликом у контейнері, ви можете вимкнути функцію AutoSize, залишити властивість максимального розміру такою, якою вона є, і вона перетворить слова саме так, як ми хочемо. KISS на роботі!
TheBlastOne

За допомогою цього розчину не можна досягти ширини рідини.
Робін

1
@Sam: Так, ви можете просто встановити належні властивості "якоря". Ви навіть пробували це?
Джон Гітцен

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

2
Я затримався OnResizeу батьків і зателефонувавmyLabel.MaximumSize = new Size(Bounds.Width, 0);
Кріс Морган

23

У моєму випадку (мітка на панелі) я встановив label.AutoSize = falseі label.Dock = Fill. І текст етикетки загортається автоматично.


Це змушує етикетку заповнити всю форму і змусити затьмарити всі інші елементи управління у формі ... Тобто, здається, це не працює. Чи є інші вимоги, які не заповнять всю форму?
Пітер Мортенсен

5
етикетка знаходиться на панелі , а не у формі безпосередньо. Тому текст не перевищує межі панелі
alex555

Гаразд, але чи не затьмарив би це всі інші елементи управління на панелі?
Пітер Мортенсен

1
Що заважає вам створити додаткову панель, що містить лише мітку?
alex555

Це здається деяким додатковим макетом, який повинен бути непотрібним. Безумовно, етикетка повинна мати власну коробку, а не потрібно її класти в іншу.
Едвін

17

Погана новина: немає властивості автозагорнути.

Хороша новина: у кінці тунелю є світло!

Ви можете виконати це програмно, щоб динамічно розмістити його, але ось найпростіше рішення:

  • Виберіть властивості етикетки
  • AutoSize = True
  • MaximumSize = ( Ширина , Висота ), де Width = Максимальний розмір, на якому ви хочете розміщувати мітку, і Height = скільки пікселів, щоб ви її загорнули

    Зразки властивостей


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події групи та оновлення ярлика MaximumSize до рівня, new Size(((Control)sender).Size.Width, 0)як було запропоновано попередньою відповіддю . Кожна сторона, зазначена у властивості Якір, добре прив’язана до відповідної внутрішньої сторони Control. Таким чином, перерахування двох протилежних сторін у Якорі ефективно встановлює розмірність управління. Прив’язка ліворуч та праворуч встановлює властивість Ширина управління, а Анкерна доверху та знизу встановлюватиме властивість Висота.

Це рішення, як 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: In 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

Проста відповідь на цю проблему полягає у зміні властивості DOCK Label. За замовчуванням це "NONE".


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
Голосувати це нормально, але принаймні скажіть, чому ви це зробили. Причина цього була визнана тим, що в WinForms не використовується <asp: Label>. Ця відповідь відповідає неправильній платформі.
theJerm

4
тому що це asp.net не winform
Trikaldarshi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.