2010-04-11 12 views
10

Gibt es andere Methoden, um ein Steuerelement an die Front außer control.BringToFront() zu bringen? Ich habe eine Reihe von Etiketten auf einem Benutzersteuerelement und wenn ich versuche, eines von ihnen nach vorne zu bringen, funktioniert es nicht. Ich habe sogar alle Kontrollen durchgegangen und ihnen alle zurückgeschickt, bis auf die, an der ich interessiert bin, und das ändert nichts.Winforms-Steuerelement nach vorne bringen

Hier ist das Verfahren, bei dem ein Etikett

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

Hier zur Benutzersteuerung hinzugefügt wird, ist die Methode, die alle von ihnen auf die Rückseite sendet.

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

Einige Beispielcode wäre nett. Sind Sie sicher, dass sich die Steuerelemente im selben Container befinden? Wenn Sie ein Steuerelement nach vorne setzen, wird es nur zum vorderen Steuerelement in seinem Container. – Patrick

+0

Dieser Beitrag half mir, genau das gleiche Problem zu lösen. – IbrarMumtaz

Antwort

14

Ja, es eine andere Möglichkeit gibt. Die Controls.SetChildIndex() ändert auch die Z-Reihenfolge. Der mit dem Index 0 ist der oberste. Kauft dir aber nichts, verwendet BringToFront() diese Methode.

Ihre SendLabelsToBack() Methode wie angegeben kann nicht funktionieren, es wird auch das Etikett an die Rückseite hinzugefügt. Aber deine nächste Aussage behebt das wieder.

Okay, das funktioniert nicht, was bedeutet, dass die BringToFront() Methode nicht ausgeführt wird. Suchen Sie im Ausgabefenster nach einer Benachrichtigung über die "erste Chance". Wie beschrieben, verursacht Ihre SendLabelsToBack() eine Ausnahme, wenn das Benutzersteuerelement ein anderes Steuerelement als ein UserLabel enthält. Stellen Sie auch einen Breakpoint nach den BringToFront() Aufruf und überprüfen Sie den Wert von userContainer.Controls[0].Name, wenn es bricht.

+0

Ich folge dem letzten Teil nicht wirklich, weil das Formular nur einmal instanziiert wird. – Nathan

+0

Nur versuchen, einen Grund zu finden, dass das Etikett nicht sichtbar sein würde. Ist es tatsächlich sichtbar, aber falsch positioniert? Oder ist es überhaupt nicht sichtbar? –

+0

Es ist hinter einem anderen Etikett sichtbar. – Nathan

3

Der Z-Index der Steuerelemente ist pro Container.

Wenn Sie BringToFront für ein Steuerelement aufrufen, das sich in einem Container befindet (z. B. Panel), wird der Container nicht nach vorne gebracht.
Daher wird das Steuerelement nur vor anderen Steuerelementen in diesem Container angezeigt.

Um zu sehen, in welchen Containern sich Ihre Steuerelemente befinden, können Sie den Bereich Dokumentgliederung im Menü Ansicht verwenden.

EDIT: Ihre userContainer Kontrolle ist wahrscheinlich hinter einem anderen Steuerelement.

4

Haben Sie versucht Invalidate() nach BringToFront()? BringToFront erhebt nicht das Paint-Ereignis

try this:

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

Ich habe es gerade versucht und das hat auch nicht geholfen. Es scheint, als ob ein paar Labels den gleichen Z-Index haben und manche nicht. Aus meiner Sicht sollten sie alle den gleichen Z-Index haben, wenn ich sie manuell setze. – Nathan

+0

Das wird nicht helfen. – SLaks

+0

das ist eine sehr gute Antwort, funktioniert völlig ... –

2

Ich denke, man muss nur die letzte Zeile:

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

dazu:

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

Wenn Wenn Sie eine Zeichenfolge als Indexer für die Controls-Auflistung verwenden, wird die Eigenschaft Name der Con verwendet trol (nicht die FieldName Eigenschaft).

Da Sie nur die zuletzt hinzugefügte Steuerelement an die Spitze zu bringen versuchen, würde dies auch funktionieren:

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

Nein; Sonst würde er eine Ausnahme bekommen. – SLaks

+0

@Slaks: basierend auf der Verwendung in der Frage, es sieht aus wie 'FieldName' würde den gleichen Wert, egal, welche Instanz, wie' FieldTop' und 'FieldLeft' usw. Also' 'FieldName' kann nur zufällig den gleichen Namen sein Als erste Instanz wird der Aufruf von BringToFront immer auf das erste Steuerelement angewendet. – MusiGenesis

+0

Warum nicht einfach 'field.BringToFront()' eingeben? Es gibt wirklich keine Notwendigkeit, es in der Kontrollsammlung zu finden, wenn er bereits einen Verweis darauf hat. – Patrick

0

Aus meiner Erfahrung sieht Windows so aus, dass alle Steuerelemente eines Grafikcontainers (Fenster, Gruppenfeld usw.) in eine Softwaresammlung eingefügt werden. Die Auflistung wird nach dem untergeordneten Index sortiert, der eine Eigenschaft jedes Steuerelements in diesem Container ist. Der Trick ist, dass Kinder mit dem gleichen Index existieren können und es auch gibt. In diesem Fall malt Windows die Kinder, die relativ zu den anderen bestellt wurden, aber zwischen ihnen werden sie in der umgekehrten Reihenfolge gezeichnet, in der sie dem Container hinzugefügt wurden.

Lange Redewendung: Für einen Container - Sie müssen sicherstellen, dass die Steuerelemente verschiedene Indizes haben, indem Sie ALLE NICHT nur EINIGE der Indizes ändern, wenn Sie die Z-Reihenfolge ändern möchten. Zum Beispiel:

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

wo indexLogic(newControl) Ihre Methode zur Berechnung des Index der besonderen Kontrolle.

Verwandte Themen