2010-04-11 35 views
10

Có phương pháp nào khác mang điều khiển đến mặt trước ngoài control.BringToFront() không? Tôi có một loạt các nhãn trên điều khiển người dùng và khi tôi cố gắng đưa một trong số chúng lên phía trước, nó không hoạt động. Tôi thậm chí đã looped thông qua tất cả các điều khiển và gửi tất cả trở lại, ngoại trừ một trong những tôi quan tâm và nó không thay đổi một điều.Mang điều khiển Winforms về phía trước

Dưới đây là phương pháp mà một nhãn được thêm vào điều khiển người dùng

private void AddUserLabel() 
{ 
    UserLabel field = new UserLabel(); 
    ++fieldNumber; 

    field.Name = "field" + fieldNumber.ToString();   

    field.Top = field.FieldTop + fieldNumber; 
    field.Left = field.FieldLeft + fieldNumber; 
    field.Height = field.FieldHeight; 
    field.Width = field.FieldWidth; 
    field.RotationAngle = field.FieldRotation; 
    field.Barcode = field.BarCoded; 
    field.HumanReadable = field.HumanReadable; 
    field.Text = field.FieldText; 
    field.ForeColor = Color.Black; 

    field.MouseDown += new MouseEventHandler(label_MouseDown); 
    field.MouseUp += new MouseEventHandler(label_MouseUp); 
    field.MouseMove += new MouseEventHandler(label_MouseMove); 

    userContainer.Controls.Add(field); 

    SendLabelsToBack(); //Send All labels to back 

    userContainer.Controls[field.FieldName].BringToFront(); 
} 

Đây là phương pháp mà sẽ gửi tất cả trong số họ để lại.

private void SendLabelsToBack() 
{ 
    foreach (UserLabel lbl in userContainer.Controls) 
    { 
     lbl.SendToBack(); 
    } 
} 
+0

Một số mã mẫu sẽ đẹp. Bạn có chắc các điều khiển nằm trong cùng một điều khiển vùng chứa hay không. Việc đặt điều khiển thành mặt trước sẽ chỉ làm cho nó trở thành điều khiển phía trước trong vùng chứa của nó. – Patrick

+0

Bài đăng này đã giúp tôi giải quyết cùng một vấn đề. – IbrarMumtaz

Trả lời

14

Yeah, có một cách khác. Controls.SetChildIndex() cũng thay đổi thứ tự Z. Người có chỉ số 0 là người đứng đầu. Tuy nhiên, không mua cho bạn bất cứ thứ gì, BringToFront() sử dụng phương pháp này.

Phương thức SendLabelsToBack() như đã cho không thể hoạt động, nó cũng sẽ gửi nhãn để thêm vào mặt sau. Nhưng tuyên bố tiếp theo của bạn sẽ sửa lại điều đó.

Được rồi, điều đó không có tác dụng, có nghĩa là phương pháp BringToFront() không được thực thi. Tìm trong cửa sổ Output cho thông báo "ngoại lệ cơ hội đầu tiên". Như được viết, SendLabelsToBack() của bạn sẽ gây ra ngoại lệ nếu điều khiển người dùng chứa bất kỳ điều khiển nào khác ngoài UserLabel. Ngoài ra, hãy đặt một breakpoint sau khi gọi số BringToFront() và kiểm tra giá trị userContainer.Controls[0].Name khi ngắt.

+0

Tôi không thực sự làm theo điều này phần cuối cùng bởi vì các hình thức chỉ là instantiated một thời gian. – Nathan

+0

Chỉ cố gắng đưa ra lý do khiến nhãn không hiển thị. Có thực tế là có thể nhìn thấy nhưng vị trí sai? Hoặc là nó không nhìn thấy được? –

+0

Nó hiển thị phía sau nhãn khác. – Nathan

3

Chỉ số z của điều khiển là mỗi vùng chứa.

Nếu bạn gọi BringToFront trên bộ điều khiển bên trong hộp chứa (chẳng hạn như Panel), nó sẽ không mang thùng chứa đến mặt trước.
Do đó, kiểm soát sẽ chỉ đi trước các điều khiển khác trong vùng chứa đó.

Để xem bộ chứa của bạn có điều khiển nào, bạn có thể sử dụng ngăn Tài liệu phác thảo trong trình đơn Chế độ xem.

EDIT: Kiểm soát userContainer của bạn có thể nằm sau một điều khiển khác.

4

Bạn đã thử Invalidate() sau BringToFront()? BringToFront không nâng cao sự kiện Sơn

thử điều này:

private void SendLabelsToBack() 
{ 
    foreach (UserLabel lbl in userContainer.Controls) 
    { 
     lbl.SendToBack(); 
     lbl.Invalidate(); 
    } 
} 
+0

Tôi vừa thử và điều đó cũng không giúp được gì. Có vẻ như một vài nhãn có cùng chỉ mục z và một số thì không. Từ sự hiểu biết của tôi, tất cả họ nên có cùng một chỉ mục z nếu tôi đặt chúng theo cách thủ công. – Nathan

+0

Điều này sẽ không giúp ích gì. – SLaks

+0

đây là câu trả lời rất hay, hoàn toàn hoạt động ... –

2

Tôi nghĩ rằng bạn chỉ cần thay đổi dòng cuối cùng của bạn:

userContainer.Controls[field.FieldName].BringToFront(); 

này:

userContainer.Controls[field.Name].BringToFront(); 

Khi bạn sử dụng một chuỗi làm chỉ mục cho bộ sưu tập Điều khiển, nó đi theo thuộc tính Name của con trol (không phải là FieldName thuộc tính).

Vì bạn đang chỉ cố gắng để mang lại sự kiểm soát hầu hết thời gian gần đây gia tăng đến đỉnh, điều này cũng sẽ làm việc:

userContainer.Controls[userContainer.Controls.Count - 1].BringToFront(); 
+0

Không; nếu không, anh ta sẽ nhận được một ngoại lệ. – SLaks

+0

@Slaks: dựa trên cách sử dụng trong câu hỏi, có vẻ như 'FieldName' sẽ trả lại cùng một giá trị bất kể trường hợp nào, chẳng hạn như' FieldTop' và 'FieldLeft' v.v. Vì vậy,' FieldName' có thể chỉ là cùng một tên là trường hợp đầu tiên, do đó, lệnh gọi đến BringToFront luôn được áp dụng cho điều khiển đầu tiên. – MusiGenesis

+0

Tại sao không gõ 'field.BringToFront()'? Có thực sự không cần phải tìm thấy nó trong bộ sưu tập kiểm soát khi ông đã có một tham chiếu đến nó. – Patrick

0

Từ kinh nghiệm của tôi, có vẻ như cửa sổ đặt tất cả các điều khiển thuộc một vùng chứa đồ họa (ngăn, hộp nhóm ... vv) trong bộ sưu tập phần mềm. Bộ sưu tập được sắp xếp theo chỉ mục con, là thuộc tính của mọi điều khiển trong vùng chứa đó. Bí quyết là trẻ em có cùng chỉ số có thể và tồn tại. Trong trường hợp này các cửa sổ sẽ vẽ những đứa trẻ đó ra lệnh liên quan đến những người khác nhưng giữa chúng nó sẽ vẽ chúng theo thứ tự ngược lại chúng đã được thêm vào thùng chứa.

Ngắn câu chuyện: cho một vùng chứa - bạn cần đảm bảo các điều khiển có chỉ mục khác nhau bằng cách thay đổi TẤT CẢ KHÔNG chỉ một số chỉ mục khi bạn muốn thay đổi thứ tự z. Ví dụ:

foreach (Control newControl in TopControl.Controls) 
{ 
    TopControl.Controls.SetChildIndex(newControl,indexlogic(newControl)); 
} 

nơi indexLogic(newControl) là phương pháp tính chỉ mục kiểm soát cụ thể.

Các vấn đề liên quan