Word quấn cho một nhãn trong Windows Forms


183

Làm cách nào chúng tôi có thể có chức năng gói từ cho nhãn trong Windows Forms ?

Tôi đặt một nhãn trong một bảng điều khiển và thêm một số văn bản để nhãn động. Nhưng nó vượt quá chiều dài bảng điều khiển. Làm sao tôi có thể giải quyết việc này?

Câu trả lời:


165

Câu trả lời nhanh: tắt AutoSize .

Vấn đề lớn ở đây là nhãn sẽ không tự động thay đổi chiều cao (chỉ chiều rộng). Để có được điều này, bạn sẽ cần phải phân lớp nhãn và bao gồm logic thay đổi kích thước dọc.

Về cơ bản những gì bạn cần làm trong OnPaint là:

  1. Đo chiều cao của văn bản (Graphics.MeasureString).
  2. Nếu chiều cao nhãn không bằng chiều cao của văn bản, đặt chiều cao và trả về.
  3. Vẽ văn bản.

Bạn cũng sẽ cần đặt cờ kiểu ResizeRedraw trong hàm tạo.


12
Chọn nhãn bạn đang tự động thêm văn bản vào. Nhìn vào các thuộc tính cho nhãn và tắt AutoSize. Bây giờ bạn sẽ có thể kéo / đặt khu vực cho nhãn và nó sẽ tự động bọc trong các tham số đó. Không cần bất kỳ mã hóa bổ sung.
madeFromCode

Đây chính xác là những gì tôi đang tìm kiếm vì nó liên quan đến việc định dạng biểu mẫu của tôi với văn bản giải thích ở dạng đoạn văn.
Philip Brack

1
@ADEFromCode Bạn cần đặt chiều cao theo chương trình nếu bạn muốn nhãn mở rộng theo chiều dọc nếu không văn bản của bạn sẽ bị cắt bớt.
Edwin

348

Trên thực tế, câu trả lời được chấp nhận là phức tạp không cần thiết.

Nếu bạn đặt nhãn thành AutoSize, nó sẽ tự động phát triển với bất kỳ văn bản nào bạn đặt trong đó. (Điều này bao gồm tăng trưởng dọc.)

Nếu bạn muốn làm cho nó bao bọc từ ở độ rộng cụ thể, bạn có thể đặt thuộc tính MaximumSize.

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

Đã thử nghiệm và hoạt động.


10
Nếu bạn có nhãn gắn vào thùng chứa của nó, bạn có thể tắt Tự động kích thước, để lại thuộc tính kích thước tối đa như hiện tại và nó sẽ bao bọc chính xác như chúng ta muốn. HÔN trong công việc!
TheBlastOne

Bạn không thể đạt được chiều rộng chất lỏng với giải pháp đó.
Robin

1
@Sam: Có, bạn có thể, bạn chỉ cần đặt thuộc tính "neo" thích hợp. Bạn đã từng thử nó chưa?
John Gietzen

1
Sam: bạn sẽ có thể đặt thuộc Docktính của cả nhãn và bảng điều khiển Top, thay vì giải pháp của tôi.
John Gietzen

2
Tôi đã bám OnResizelấy phụ huynh và gọimyLabel.MaximumSize = new Size(Bounds.Width, 0);
Chris Morgan

23

Trong trường hợp của tôi (nhãn trên bảng) tôi đặt label.AutoSize = falselabel.Dock = Fill. Và văn bản nhãn được bọc tự động.


Điều này làm cho nhãn điền vào toàn bộ biểu mẫu và làm cho nó che khuất tất cả các điều khiển khác trong biểu mẫu ... Có nghĩa là, nó dường như không hoạt động. Có yêu cầu nào khác mà nó sẽ không điền vào toàn bộ biểu mẫu không?
Peter Mortensen

5
nhãn nằm trên một bảng điều khiển , không phải trên mẫu trực tiếp. Do đó, văn bản không vượt quá giới hạn của bảng điều khiển
alex555

OK, nhưng sau đó nó sẽ không làm mờ tất cả các điều khiển khác trong bảng điều khiển?
Peter Mortensen

1
Điều gì ngăn bạn tạo một bảng điều khiển phụ chỉ chứa nhãn?
alex555

Điều đó có vẻ như một số bố trí thêm nên không cần thiết. Chắc chắn nhãn nên có hộp riêng của nó chứ không cần phải đặt vào hộp khác.
Edwin

17

Tin xấu: không có tài sản autowrap.

Tin tốt: có một ánh sáng ở cuối đường hầm!

Bạn có thể thực hiện điều này theo chương trình để kích thước nó một cách linh hoạt, nhưng đây là giải pháp đơn giản nhất:

  • Chọn các thuộc tính của nhãn
  • Tự động kích thước = Đúng
  • MaximumSize = ( Width , height ) trong đó Width = max size bạn muốn nhãn là và Chiều cao = bao nhiêu pixel bạn muốn nó bao bọc

    Thuộc tính mẫu


4
Thêm một lưu ý nữa, nếu bạn để chiều cao tối đa ở mức 0, nó sẽ tiếp tục mở rộng theo chiều dọc.
nhợt nhạt

Nhãn của tôi không có thuộc tính AutoSize và MaximumSize, làm cách nào để thêm các thuộc tính này?
mrbengi

11

Từ MSDN , Tự động bọc văn bản trong nhãn :

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

Để ngắt các ký tự thay vì các từ (hữu ích khi bạn có các chuỗi dài không có khoảng trắng như đường dẫn tệp), hãy sử dụng (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl) để thay thế. Xem bài cuối cùng trong cùng một chủ đề MSDN.
Ohad Schneider

1
Ngoài ra, đừng quên bao gồm phần đệm trên và dưới của nhãn trong phép tính ( Height = sz.Height + Padding.Vertical;)
Igor Brejc

6

Tôi đã phải tìm một giải pháp nhanh chóng, vì vậy tôi chỉ sử dụng một TextBox với các thuộc tính đó:

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

Đây là một giải pháp tốt, nhưng tôi có thể thích sử dụng ReadOnly để đặt Bật thành sai.
PahJoker

1
Đây là một giải pháp giàu trí tưởng tượng cũng hoạt động tốt trên Compact Framework (nơi Nhãn không có thuộc tính AutoSize và MaximumSize).
Tim Coulter

3

Có một câu hỏi hay hơn dựa trên câu trả lời của @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; điều này cho phép bạn sử dụng nhãn tự động phát triển khi được gắn vào cha mẹ, ví dụ như bảng điều khiển.

this.Height = sz.Height + Padding.Bottom + Padding.Top; ở đây chúng tôi chăm sóc phần đệm cho phần trên và phần dưới.


1
  1. Đặt nhãn bên trong một bảng điều khiển
  2. Xử lý ClientSizeChanged eventbảng điều khiển, làm cho nhãn điền vào chỗ trống:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. Đặt Auto-Sizecho nhãn thànhtrue

  4. Đặt Dockcho nhãn thànhFill

Là bước 3 và 4 được thực hiện trong thiết kế? Bất kỳ lý do tại sao họ là bước 3 và 4?
Rabbi tàng hình

Chúng được thực hiện trong trình thiết kế (nhưng có thể được thực hiện bằng mã nếu bạn cần) và không có lý do nào để đặt hàng.
noelicus

1

Bạn không chắc chắn nó sẽ phù hợp với tất cả các trường hợp sử dụng nhưng tôi thường sử dụng một thủ thuật đơn giản để có được những hành vi gói: đặt của bạn Labelvới AutoSize=falsebên trong một 1x1 TableLayoutPanelmà sẽ chăm sóc của các Labelkích thước 's.


1

Đặt Thuộc tính AutoEllipsis thành 'TRUE' và AutoSize property thành 'FALSE'.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


0

Nếu bảng điều khiển của bạn giới hạn độ rộng của nhãn, bạn có thể đặt thuộc tính Anchor của nhãn thành Trái, Phải và đặt Tự động kích thước thành đúng. Đây là khái niệm tương tự như lắng nghe SizeChangedsự kiện của Hội đồng và cập nhật MaximumSize của nhãn thành new Size(((Control)sender).Size.Width, 0)như được đề xuất bởi câu trả lời trước đó . Tất cả các bên được liệt kê trong thuộc tính Anchor đều được neo vào bên trong tương ứng của Control. Vì vậy, liệt kê hai mặt đối diện trong Anchor đặt hiệu quả kích thước của điều khiển. Neo sang trái và phải đặt thuộc tính Width của Control và Neo ở trên và dưới sẽ đặt thuộc tính Chiều cao của nó.

Giải pháp này, như C #:

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

Không hoạt động. Nhãn tăng chiều rộng của bảng điều khiển của tôi chỉ là nó không phải bọc. Thật không may, cửa sổ không rộng bằng.
ygoe

0

Nếu bạn thực sự muốn đặt chiều rộng nhãn độc lập với nội dung, tôi thấy rằng cách dễ nhất là:

  • Đặt tự động đúng
  • Đặt chiều rộng tối đa theo cách bạn muốn
  • Đặt chiều rộng tối thiểu giống hệt nhau

Bây giờ nhãn có chiều rộng không đổi, nhưng nó tự động điều chỉnh chiều cao của nó.

Sau đó, cho văn bản động, giảm kích thước phông chữ. Nếu cần, hãy sử dụng đoạn mã này trong phần phụ nơi đặt văn bản nhãn:

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

Điều này đã giúp tôi trong Biểu mẫu của mình được gọi là 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);
}

Toàn bộ mã mẫu của tôi


0

Nếu kích thước của nút cần được giữ nguyên:

myButton.Text = "word\r\nwrapped"

0

Câu trả lời đơn giản cho vấn đề này là thay đổi thuộc tính DOCK của Nhãn. Đó là "KHÔNG" theo mặc định.


0

Nếu bạn đang nhập văn bản vào nhãn trước, bạn có thể làm điều này.

  1. Trong trình thiết kế, Nhấp chuột phải vào nhãn và nhấp vào Thuộc tính.
  2. Trong Thuộc tính, tìm kiếm tab văn bản.
  3. Nhấp vào tab và nhấp vào nút mũi tên bên cạnh.
  4. Một hộp sẽ bật lên trên nó.
  5. Bạn có thể nhấn enter trong hộp bật lên để thêm dòng và gõ như trong notepad! (ENTER BÁO CHÍ Ở ĐÂU BẠN MUỐN VIẾT VĂN BẢN LABEL)

-12

Sử dụng style="overflow:Scroll"trong nhãn như trong HTML dưới đây. Điều này sẽ thêm thanh cuộn trong nhãn trong bảng điều khiển.

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

3
Bỏ phiếu này là tốt, nhưng ít nhất hãy nói lý do tại sao bạn làm điều đó. Lý do điều này đã được bỏ phiếu là vì <asp: Nhãn> không được sử dụng trong WinForms. Câu trả lời này là cho nền tảng sai.
theJerm

4
bởi vì đó là asp.net không phải dạng winform
Trikaldarshi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.