ตัดคำสำหรับฉลากในแบบฟอร์ม Windows


184

หนึ่งจะได้รับฟังก์ชั่นการตัดคำLabelสำหรับข้อความที่ออกไปนอกขอบเขตได้อย่างไร

คำตอบ:


167

คำตอบอย่างรวดเร็ว: สลับปิด AutoSize

ปัญหาใหญ่ที่นี่คือฉลากจะไม่เปลี่ยนความสูงโดยอัตโนมัติ (เฉพาะความกว้าง) เพื่อให้ได้รับสิทธินี้คุณจะต้องซับคลาสของฉลากและรวมตรรกะการปรับขนาดแนวตั้ง

โดยทั่วไปสิ่งที่คุณต้องทำใน OnPaint คือ:

  1. วัดความสูงของข้อความ (Graphics.MeasureString)
  2. หากความสูงของฉลากไม่เท่ากับความสูงของข้อความให้ตั้งค่าความสูงและผลตอบแทน
  3. วาดข้อความ

คุณจะต้องตั้งค่าสถานะลักษณะResizeRedrawในตัวสร้าง


12
เลือกป้ายกำกับที่คุณเพิ่มข้อความแบบไดนามิก ดูคุณสมบัติของฉลากและปิดการปรับขนาดอัตโนมัติ ตอนนี้คุณจะสามารถลาก / ตั้งค่าพื้นที่สำหรับป้ายกำกับและมันจะตัดคำอัตโนมัติเพื่อให้อยู่ในพารามิเตอร์เหล่านั้นโดยอัตโนมัติ ไม่จำเป็นต้องมีการเข้ารหัสเพิ่มเติมใด ๆ
madeFromCode

นี่คือสิ่งที่ฉันกำลังมองหาเนื่องจากเกี่ยวข้องกับการจัดรูปแบบฟอร์มของฉันด้วยข้อความอธิบายที่อยู่ในรูปแบบย่อหน้า
Philip Brack

1
@madeFromCode คุณจะต้องตั้งค่าความสูงโดยทางโปรแกรมหากคุณต้องการให้ฉลากขยายในแนวตั้งมิฉะนั้นข้อความของคุณจะถูกตัด
Edwin

348

ที่จริงแล้วคำตอบที่ยอมรับนั้นซับซ้อนโดยไม่จำเป็น

หากคุณตั้งค่าป้ายกำกับเป็น AutoSize มันจะเติบโตโดยอัตโนมัติพร้อมข้อความที่คุณใส่ไว้ (ซึ่งรวมถึงการเติบโตในแนวดิ่ง)

ถ้าคุณต้องการทำให้เป็นคำที่มีความกว้างเฉพาะคุณสามารถตั้งค่าคุณสมบัติ MaximumSize ได้

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

ผ่านการทดสอบและทำงาน


10
หากคุณมีป้ายกำกับติดอยู่ในคอนเทนเนอร์คุณสามารถปิดการปรับขนาดอัตโนมัติออกจากคุณสมบัติขนาดสูงสุดตามที่มันเป็นและจะตัดคำให้ตรงตามที่เราต้องการ จูบที่ทำงาน!
TheBlastOne

คุณไม่สามารถให้ความกว้างของของไหลกับสารละลายนั้นได้
Robin

1
@ Sam: ใช่คุณทำได้คุณเพียงแค่ตั้งค่าคุณสมบัติ "anchor" ที่เหมาะสม คุณเคยลองไหม
John Gietzen

1
แซม: คุณควรจะสามารถตั้งค่าDockคุณสมบัติของทั้งฉลากและพาเนลได้Topแทนที่จะเป็นโซลูชันของฉัน
John Gietzen

2
ฉันได้ผูกไว้กับOnResizeผู้ปกครองและโทรmyLabel.MaximumSize = new Size(Bounds.Width, 0);
Chris Morgan

23

ในกรณีของฉัน (ป้ายบนแผง) ผมตั้งและlabel.AutoSize = false label.Dock = Fillและข้อความฉลากจะถูกห่อโดยอัตโนมัติ


สิ่งนี้ทำให้ป้ายกำกับกรอกแบบฟอร์มทั้งหมดและทำให้ปิดบังตัวควบคุมอื่น ๆ ทั้งหมดในแบบฟอร์ม ... นั่นคือดูเหมือนจะไม่ทำงาน มีข้อกำหนดอื่น ๆ หรือไม่ที่จะไม่กรอกแบบฟอร์มทั้งหมด?
Peter Mortensen

5
ฉลากอยู่บนพาเนลไม่ใช่ในแบบฟอร์มโดยตรง ดังนั้นข้อความจะต้องไม่เกินขอบเขตของแผงควบคุม
alex555

ตกลง แต่จะไม่ปิดบังการควบคุมอื่น ๆ ทั้งหมดในแผงควบคุมหรือไม่
Peter Mortensen

1
อะไรทำให้คุณไม่สามารถสร้างแผงเพิ่มเติมที่มีเฉพาะฉลากได้
alex555

ที่ดูเหมือนว่ารูปแบบพิเศษบางอย่างที่ไม่จำเป็น แน่นอนฉลากควรมีกล่องของตัวเองแทนที่จะต้องใส่ในกล่องอื่น
Edwin

17

ไม่มีคุณสมบัติ autowrap แต่สามารถทำได้โดยทางโปรแกรมเพื่อกำหนดขนาดแบบไดนามิก นี่คือทางออกหนึ่ง:

  • เลือกคุณสมบัติของฉลาก

  • AutoSize = True

  • MaximumSize= ( ความกว้าง , ความสูง ) ที่กว้าง = ขนาดสูงสุดที่คุณต้องการฉลากจะเป็นและความสูง = จำนวนพิกเซลที่คุณต้องการให้ห่อ

    ตัวอย่างคุณสมบัติ


4
อีกหนึ่งบันทึกย่อถ้าคุณปล่อยให้ความสูงสูงสุดอยู่ที่ 0 มันจะขยายตัวในแนวตั้งต่อไป
palehorse

ป้ายกำกับของฉันไม่มีคุณสมบัติ 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 เดียวกัน
Ohad Schneider

1
นอกจากนี้อย่าลืมใส่ช่องว่างด้านบนและด้านล่างของป้ายกำกับไว้ในการคำนวณ ( Height = sz.Height + Padding.Vertical;)
Igor Brejc

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 เป็นเท็จ
PahJoker

1
นี่เป็นโซลูชันเชิงจินตนาการที่ทำงานได้ดีบน Compact Framework (โดยที่ Label ไม่มีคุณสมบัติ AutoSize และ MaximumSize)
Tim Coulter

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?
Stealth Rabbi

พวกเขาทำในการออกแบบ (แต่สามารถทำได้ในรหัสถ้าคุณต้องการ) และไม่มีเหตุผลสำหรับการสั่งซื้อ
noelicus

1

ไม่แน่ใจว่ามันจะพอดีกับการใช้งานในทุกกรณี แต่ฉันมักจะใช้เคล็ดลับง่ายๆที่จะได้รับพฤติกรรมการตัด: ใส่ของคุณLabelที่มีAutoSize=falseอยู่ภายในขนาด 1x1 TableLayoutPanelซึ่งจะดูแลLabel's ขนาด



0

หากพาเนลของคุณจำกัดความกว้างของฉลากคุณสามารถตั้งค่าคุณสมบัติ Anchor ของฉลากเป็นซ้าย, ขวาและตั้งค่าขนาดอัตโนมัติเป็นจริง นี่คือแนวคิดคล้ายกับการฟังสำหรับแผงSizeChangedเหตุการณ์และปรับปรุง MaximumSize ฉลากไปnew Size(((Control)sender).Size.Width, 0)ตามที่แนะนำโดยคำตอบที่ก่อนหน้านี้ ทุกด้านที่ระบุไว้ในคุณสมบัติ Anchor นั้นดียึดกับด้านในของตัวควบคุมที่มี ดังนั้นการแสดงสองฝั่งตรงข้ามใน Anchor จึงกำหนดขนาดของตัวควบคุมอย่างมีประสิทธิภาพ การยึดกับด้านซ้ายและขวาจะเป็นการตั้งค่าคุณสมบัติความกว้างของตัวควบคุมและการยึดกับด้านบนและด้านล่างจะเป็นการตั้งค่าคุณสมบัติความสูง

วิธีนี้เป็น C #:

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

ใช้งานไม่ได้ Label เพิ่มความกว้างของพาเนลของฉันโดยที่ไม่ต้องพันตัว น่าเสียดายที่หน้าต่างนั้นไม่กว้าง
ygoe

0

หากคุณต้องการตั้งค่าความกว้างของฉลากโดยไม่ขึ้นกับเนื้อหาฉันพบว่าวิธีที่ง่ายที่สุดคือ:

  • ตั้งค่าการทำให้เป็นจริงโดยอัตโนมัติ
  • ตั้งค่าความกว้างสูงสุดตามที่คุณต้องการ
  • ตั้งค่าความกว้างขั้นต่ำเหมือนกัน

ตอนนี้ฉลากมีความกว้างคงที่ แต่ปรับความสูงได้โดยอัตโนมัติ

จากนั้นสำหรับข้อความไดนามิกลดขนาดตัวอักษร หากจำเป็นให้ใช้ตัวอย่างนี้ในส่วนย่อยที่ตั้งค่าข้อความฉลาก:

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

คำตอบง่ายๆสำหรับปัญหานี้คือการเปลี่ยนคุณสมบัติ DOCK ของ Label มันคือ "ไม่มี" โดยค่าเริ่มต้น


0

หากคุณป้อนข้อความลงในฉลากล่วงหน้าคุณสามารถทำได้

  1. ในตัวออกแบบคลิกขวาบนป้ายชื่อและคลิกคุณสมบัติ
  2. ในคุณสมบัติค้นหาแท็บข้อความ
  3. คลิกที่แท็บและคลิกที่ปุ่มลูกศรถัดจากมัน
  4. กล่องจะปรากฏขึ้นด้านบนของมัน
  5. คุณสามารถกด Enter ในกล่องป๊อปอัพเพื่อเพิ่มบรรทัดและพิมพ์ใน notepad! (กด 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.