Zeilenumbruch für eine Beschriftung in Windows Forms


183

Wie können wir die Zeilenumbruchfunktion für ein Etikett in Windows Forms erhalten ?

Ich habe eine Beschriftung in ein Bedienfeld eingefügt und Text hinzugefügt, um sie dynamisch zu beschriften. Aber es überschreitet die Plattenlänge. Wie kann ich das lösen?

Antworten:


165

Die schnelle Antwort: Schalten Sie AutoSize aus .

Das große Problem hierbei ist, dass das Etikett seine Höhe nicht automatisch ändert (nur die Breite). Um dies richtig zu machen, müssen Sie die Beschriftung in Unterklassen unterteilen und die vertikale Größenänderungslogik einbeziehen.

Grundsätzlich müssen Sie in OnPaint Folgendes tun:

  1. Messen Sie die Höhe des Texts (Graphics.MeasureString).
  2. Wenn die Beschriftungshöhe nicht der Höhe des Texts entspricht, stellen Sie die Höhe ein und kehren Sie zurück.
  3. Zeichnen Sie den Text.

Sie müssen auch das ResizeRedraw-Stilflag im Konstruktor setzen.


12
Wählen Sie die Beschriftung aus, zu der Sie dynamisch Text hinzufügen. Sehen Sie sich die Eigenschaften für die Beschriftung an und deaktivieren Sie AutoSize. Sie können jetzt den Bereich für das Etikett ziehen / festlegen und es wird automatisch umbrochen, um innerhalb dieser Parameter zu bleiben. Keine zusätzliche Codierung erforderlich.
madeFromCode

Dies ist genau das, wonach ich gesucht habe, da es sich um die Formatierung meines Formulars mit erklärendem Text handelt, der in Absatzform vorliegt.
Philip Brack

1
@madeFromCode Sie müssen die Höhe programmgesteuert festlegen, wenn die Beschriftung vertikal erweitert werden soll, da sonst Ihr Text abgeschnitten wird.
Edwin

348

Tatsächlich ist die akzeptierte Antwort unnötig kompliziert.

Wenn Sie die Beschriftung auf AutoSize setzen, wächst sie automatisch mit dem darin enthaltenen Text. (Dies schließt vertikales Wachstum ein.)

Wenn Sie den Zeilenumbruch auf eine bestimmte Breite einstellen möchten, können Sie die MaximumSize-Eigenschaft festlegen.

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

Getestet und funktioniert.


10
Wenn Sie das Etikett in den Container einrasten lassen, können Sie AutoSize deaktivieren, die Eigenschaft max size so lassen, wie sie ist, und es wird genau so umbrochen, wie wir es möchten. KUSS bei der Arbeit!
TheBlastOne

Mit dieser Lösung können Sie keine Flüssigkeitsbreite erreichen.
Robin

1
@Sam: Ja, Sie können einfach die richtigen "Anker" -Eigenschaften festlegen. Hast du es überhaupt versucht?
John Gietzen

1
Sam: Sie sollten in der Lage sein, die DockEigenschaft von Beschriftung und Bedienfeld Topanstelle meiner Lösung auf festzulegen.
John Gietzen

2
Ich habe mich an OnResizedie Eltern geklammert und angerufenmyLabel.MaximumSize = new Size(Bounds.Width, 0);
Chris Morgan

23

In meinem Fall (Etikett auf einer Tafel) setze ich label.AutoSize = falseund label.Dock = Fill. Und der Etikettentext wird automatisch umbrochen.


Dadurch füllt das Etikett das gesamte Formular aus und verdeckt alle anderen Steuerelemente im Formular ... Das heißt, es scheint nicht zu funktionieren. Gibt es andere Anforderungen, die nicht das gesamte Formular ausfüllen?
Peter Mortensen

5
Das Etikett befindet sich auf einer Tafel , nicht direkt auf dem Formular. Daher überschreitet der Text nicht die Grenzen des Panels
alex555

OK, aber würde es dann nicht alle anderen Steuerelemente im Bedienfeld verdecken?
Peter Mortensen

1
Was hindert Sie daran, ein zusätzliches Bedienfeld zu erstellen, das nur das Etikett enthält?
Alex555

Das scheint ein zusätzliches Layout zu sein, das unnötig sein sollte. Sicherlich sollte das Etikett eine eigene Schachtel haben, anstatt in eine andere Schachtel gelegt werden zu müssen.
Edwin

17

Schlechte Nachrichten: Es gibt keine Autowrap-Eigenschaft.

Gute Nachricht: Am Ende des Tunnels leuchtet ein Licht!

Sie können dies programmgesteuert durchführen, um die Größe dynamisch zu bestimmen. Hier ist jedoch die einfachste Lösung:

  • Wählen Sie die Eigenschaften des Etiketts aus
  • AutoSize = True
  • MaximumSize = ( Breite , Höhe ) wobei Breite = maximale Größe, die das Etikett haben soll, und Höhe = wie viele Pixel es umbrechen soll

    Beispieleigenschaften


4
Noch ein Hinweis: Wenn Sie die maximale Höhe bei 0 belassen, wird sie weiterhin vertikal erweitert.
Palehorse

Mein Label verfügt nicht über die Eigenschaften AutoSize und MaximumSize. Wie kann ich diese hinzufügen?
Mrbengi

11

Von MSDN , automatisch Wrap Text in Label - :

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();
    }
}

Verwenden Sie stattdessen (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl), um Zeichen anstelle von Wörtern zu unterbrechen (nützlich, wenn Sie lange Zeichenfolgen ohne Leerzeichen wie Dateipfade haben). Siehe den letzten Beitrag im selben MSDN-Thread.
Ohad Schneider

1
Vergessen Sie auch nicht, die obere und untere Polsterung des Etiketts in die Berechnung einzubeziehen ( Height = sz.Height + Padding.Vertical;)
Igor Brejc

6

Ich musste eine schnelle Lösung finden, also habe ich nur eine TextBox mit diesen Eigenschaften verwendet:

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
                    };

Dies ist eine gute Lösung, aber ich würde es vielleicht vorziehen, ReadOnly zu verwenden, um Enabled auf false zu setzen.
PahJoker

1
Dies ist eine einfallsreiche Lösung, die auch in Compact Framework gut funktioniert (wo Label keine AutoSize- und MaximumSize-Eigenschaften hat).
Tim Coulter

3

Haben Sie eine bessere basierend auf der Antwort von @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; Auf diese Weise können Sie das automatisch wachsende Etikett verwenden, wenn es an ein übergeordnetes Element, z. B. ein Bedienfeld, angedockt ist.

this.Height = sz.Height + Padding.Bottom + Padding.Top; hier kümmern wir uns um die Polsterung für oben und unten.


1
  1. Legen Sie das Etikett in eine Platte
  2. Behandeln Sie das ClientSizeChanged eventfür das Panel, damit das Etikett den Raum ausfüllt:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. Stellen Sie Auto-Sizefür das Etikett auf eintrue

  4. Stellen Sie Dockfür das Etikett auf einFill

Werden die Schritte 3 und 4 im Designer ausgeführt? Gibt es einen Grund, warum sie Schritt 3 und 4 sind?
Stealth Rabbi

Sie werden im Designer erstellt (können aber bei Bedarf auch im Code ausgeführt werden), und es gibt keinen Grund für die Bestellung.
Noelicus

1

Ich bin mir nicht sicher, ob es für alle Anwendungsfälle geeignet ist, aber ich verwende oft einen einfachen Trick, um das Umhüllungsverhalten zu ermitteln: Legen Sie Ihr Labelwith AutoSize=falsein ein 1x1, TableLayoutPaneldas sich um die LabelGröße des Geräts kümmert .


1

Setzen Sie die AutoEllipsis-Eigenschaft auf 'TRUE' und die AutoSize-Eigenschaft auf 'FALSE'.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein


0

Wenn Ihr Bedienfeld die Breite Ihres Etiketts begrenzt, können Sie die Anchor-Eigenschaft Ihres Etiketts auf Left, Right und AutoSize auf true setzen. Dies ähnelt konzeptionell dem Abhören des SizeChangedEreignisses des Panels und dem Aktualisieren der MaximumSize des Labels auf a, new Size(((Control)sender).Size.Width, 0)wie in einer vorherigen Antwort vorgeschlagen . Jede Seite, die in der Anchor-Eigenschaft aufgeführt ist, ist auf der jeweiligen Innenseite des enthaltenen Steuerelements verankert. Wenn Sie also zwei gegenüberliegende Seiten in Anchor auflisten, wird die Dimension des Steuerelements effektiv festgelegt. Durch Verankerung nach links und rechts wird die Width-Eigenschaft des Steuerelements festgelegt, und durch Verankerung nach oben und unten wird die Height-Eigenschaft festgelegt.

Diese Lösung als C #:

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

Funktioniert nicht Das Etikett vergrößert die Breite meines Panels, nur dass es nicht umwickelt werden muss. Leider ist das Fenster nicht so breit.
Ygoe

0

Wenn Sie die Etikettenbreite wirklich unabhängig vom Inhalt einstellen möchten, ist dies meiner Meinung nach der einfachste Weg:

  • Setzen Sie autosize auf true
  • Stellen Sie die maximale Breite so ein, wie Sie es möchten
  • Stellen Sie die Mindestbreite identisch ein

Jetzt hat das Etikett eine konstante Breite, passt seine Höhe jedoch automatisch an.

Verringern Sie dann für dynamischen Text die Schriftgröße. Verwenden Sie dieses Snippet bei Bedarf in dem Unterabschnitt, in dem der Beschriftungstext festgelegt ist:

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

Dies hat mir in meinem Formular namens InpitWindow geholfen: 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);
}

Ganzer Code meines Formulars


0

Wenn die Abmessungen der Schaltfläche unverändert bleiben müssen:

myButton.Text = "word\r\nwrapped"

0

Die einfache Antwort auf dieses Problem besteht darin, die DOCK-Eigenschaft des Labels zu ändern. Es ist standardmäßig "NONE".


0

Wenn Sie zuvor Text in das Etikett eingeben, können Sie dies tun.

  1. Klicken Sie im Designer mit der rechten Maustaste auf die Beschriftung und klicken Sie auf Eigenschaften.
  2. Suchen Sie unter Eigenschaften nach der Registerkarte Text.
  3. Klicken Sie auf die Registerkarte und dann auf die Pfeilschaltfläche daneben.
  4. Darüber wird ein Feld eingeblendet.
  5. Sie können die Eingabetaste im Popup-Feld drücken, um Zeilen hinzuzufügen und wie im Editor einzugeben! (Drücken Sie die Eingabetaste, wo Sie den Etikettentext verpacken möchten.)

-12

Verwenden Sie style="overflow:Scroll"im Etikett wie im folgenden HTML. Dadurch wird die Bildlaufleiste in der Beschriftung im Bedienfeld hinzugefügt.

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

3
Die Abstimmung ist in Ordnung, aber sagen Sie zumindest, warum Sie es getan haben. Der Grund, warum dies abgelehnt wurde, ist, dass in WinForms kein <asp: Label> verwendet wird. Diese Antwort ist für die falsche Plattform.
theJerm

4
weil es asp.net nicht winform ist
Trikaldarshi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.