Wie können wir die Word-Wrap-Funktionalität für eine Beschriftung in Windows Forms erhalten?
Ich habe eine Beschriftung in ein Bedienfeld eingefügt und der Beschriftung dynamisch Text hinzugefügt. Sie überschreitet jedoch die Plattenlänge. Wie kann ich das lösen?
Die schnelle Antwort: Schalten Sie aus AutoSize .
Das große Problem hierbei ist, dass das Etikett seine Höhe nicht automatisch ändert (nur die Breite). Um dies zu erreichen, müssen Sie die Beschriftung in Unterklassen unterteilen und die vertikale Größenänderungslogik einbeziehen.
Grundsätzlich müssen Sie in OnPaint Folgendes tun:
Sie müssen auch das Stil-Flag ResizeRedraw im Konstruktor setzen.
Tatsächlich ist die akzeptierte Antwort unnötig kompliziert.
Wenn Sie die Beschriftung auf AutoSize einstellen, wird sie automatisch mit dem eingegebenen Text vergrößert. (Dies schließt vertikales Wachstum ein.)
Wenn Sie den Zeilenumbruch auf eine bestimmte Breite festlegen möchten, können Sie die MaximumSize-Eigenschaft festlegen.
myLabel.MaximumSize = new Size(100, 0);
myLabel.AutoSize = true;
Getestet und funktioniert.
In meinem Fall (Etikett auf einem Panel) setze ich label.AutoSize = false
und label.Dock = Fill
. Und der Etikettentext wird automatisch umgebrochen.
Schlechte Nachrichten: Es gibt keine Autowrap-Eigenschaft.
Gute Nachricht: Am Ende des Tunnels brennt ein Licht!
Sie können dies programmgesteuert durchführen, um die Größe dynamisch anzupassen. Hier ist jedoch die einfachste Lösung:
MaximumSize = (Breite, Höhe) wobei Breite = die maximale Größe, die das Etikett haben soll, und Höhe = wie Viele Pixel, die umgebrochen werden sollen
Von MSDN , Text automatisch in Beschriftung umbrechen :
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();
}
}
Ich musste eine schnelle Lösung finden, also habe ich einfach eine TextBox mit den folgenden 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
};
Habe 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;
Damit können Sie die automatische Beschriftung verwenden, wenn Sie an ein übergeordnetes Element angedockt sind, z. ein Panel.
this.Height = sz.Height + Padding.Bottom + Padding.Top;
hier kümmern wir uns um die Polsterung von oben und unten.
Ich bin mir nicht sicher, ob es für alle Anwendungsfälle geeignet ist, aber ich verwende oft einen einfachen Trick, um das Umbruchverhalten zu ermitteln: Setzen Sie Ihr Label
mit AutoSize=false
in einem 1x1 TableLayoutPanel
, der sich um die Größe des Label
kümmert.
Behandle das ClientSizeChanged event
für das Bedienfeld, wobei 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);
}
Einstellen Auto-Size
für das Label zu true
Dock
für das Label auf Fill
Die einfache Antwort auf dieses Problem besteht darin, die DOCK-Eigenschaft des Labels zu ändern. Es ist standardmäßig "NONE".
Wenn die Abmessungen der Schaltfläche unverändert bleiben sollen:
myButton.Text = "Word\r\nwrapped"
Wenn Sie die Etikettenbreite wirklich unabhängig vom Inhalt festlegen möchten, ist dies der einfachste Weg:
Das Etikett hat jetzt eine konstante Breite, passt seine Höhe jedoch automatisch an.
Verringern Sie dann für dynamischen Text die Schriftgröße. Verwenden Sie bei Bedarf dieses Snippet in dem Unterabschnitt, in dem der Bezeichnungstext 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
Dies half mir in meinem Formular namens 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);
}
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 Ereignisses SizeChanged
des Panels und dem Aktualisieren der maximalen Größe des Labels auf new Size(((Control)sender).Size.Width, 0)
, wie von eine vorherige Antwort vorgeschlagen. Jede in der Anchor-Eigenschaft aufgeführte Seite ist gut an der jeweiligen Innenseite des enthaltenden Steuerelements verankert. Wenn Sie also zwei gegenüberliegende Seiten in Anchor auflisten, wird die Dimension des Steuerelements effektiv festgelegt. Wenn Sie links und rechts verankern, wird die Width-Eigenschaft des Steuerelements festgelegt, und wenn Sie oben und unten verankern, wird die Height-Eigenschaft festgelegt.
Diese Lösung, als C #:
label.Anchor = AnchorStyles.Left | AnchorStyles.Right;
label.AutoSize = true;