2009-05-28 2 views
1

Ich habe ein Steuerelement, das mehrere C# -Bedienelemente in meiner GUI überlagern kann. Diese Steuerung verfügt über einen halbtransparenten Hintergrund, um ‚grau-out‘ Teile der GUI und die Klasse sieht some wie folgt aus:C# Winforms: Aktualisieren eines Teils einer GUI (enthält 1 oder mehr Steuerelemente)

public greyOutControl: UserControl 
{ 
    // Usual stuff here 

    protected overide OnPaint() 
    { 
     paintBackround(); 

     base.OnPaint(); 
    } 
} 

Derzeit ist die Steuerung manchmal in einer Schleife gefangen wird und immer wieder neu zieht die Hintergrund, wodurch die halbtransparente Farbe immer weniger transparent erscheint.

Meine Idee, dies zu bekämpfen, ist die folgende (in groben Zügen):

1) Bestimmen Sie, was steuert der greyOutControl oben ist von 2) ruft Refresh() auf diesen Kontrollen die Anzeige 3) zu aktualisieren, zeichne weiter das greyOutControl.

Meine Frage ist: Wie kann ich feststellen, welche Steuerelemente das greyOutControl überlappt? Oder gibt es eine Möglichkeit, nur den Teil der GUI zu aktualisieren, den greyOutControl abdeckt?

Antwort

0

Die Lösung für dieses Problem, die ich gefunden habe, war, einen Screenshot des zu überlagernden Bereichs zu erstellen und dann dieses Bild als Hintergrund für das Steuerelement zu verwenden, das überlagert wird. Dies ermöglicht Ihnen dann, das Alpha-Overlay in das Bild innerhalb der OnPaint() -Methode und das Steuerelement zu setzen, um sich selbst korrekt zu zeichnen.

Dies hat den Nachteil, dass der Hintergrund im überlappenden Steuerelement nicht aktualisiert wird, aber es sei denn, es gab eine Reihe von Ereignisprozeduren, die beobachten, wenn sich etwas ändert und dann das überlagerte Steuerelement aktualisieren. Manchmal bereue ich es nicht, WPF zu benutzen!

0

Ich sehe keinen direkten Weg, die überlappenden Kontrollen zu finden. Ich denke, Sie müssen vielleicht den gesamten Kontrollbaum überprüfen, um das herauszufinden. Über die Aktualisierung können Sie die Methode Control.Invalidate(Rectangle) verwenden, um anzugeben, welcher Teil aktualisiert werden soll.

+0

Das Problem mit dem Aufruf von Invalidate() ist, dass nicht garantiert werden kann, dass Invalidate sofort aufgerufen wird, sondern die Dokumentation gibt an, dass es zum nächsten günstigen Zeitpunkt aufgerufen wird. Innerhalb der OnPaint() - Funktion ist es wichtig, dass der Hintergrund vollständig gerendert wird, bevor Sie versuchen, das halbtransparente Overlay hinzuzufügen. Daher ist Refresh() bevorzugt. –

2

Warum behalten Sie Ihre transparenten Steuerelemente nicht im Auge und malen sie erst, nachdem alle anderen Steuerelemente gezeichnet wurden? Wenn Sie etwas an der Spitze der Z-Reihenfolge malen, sollten die anderen Steuerelemente nicht neu gezeichnet werden.

+0

Im Wesentlichen zeige/Verstecke ich das transparente Steuerelement nur bei Bedarf, d. H. Über allen anderen Steuerelementen. Der Grund, warum mehr benötigt wird, liegt an der Tatsache, dass die transparenten Teile der Steuerung mehrmals neu gestrichen werden, was einen unerwünschten Effekt verursacht. Daher wollte ich, wenn das Control neu gezeichnet wird, dass es vollständig mit den richtigen transparenten Bereichen gerendert wird. –

+1

Haben Sie versucht, base.OnPaint() nicht aufzurufen? – Trap

+0

Derzeit bin ich benutzerdefinierte Rendering der Hintergrund (d. H. Die transparenten Teile) und ich lasse die C# -Bibliothek das Rendering aller nichttransparenten Teile der Steuerung z. Tasten, Text usw. Ich bin sicher, dass es möglich wäre, den Anruf vollständig zu base.OnPain zu entfernen, ist es derzeit wegen der erhöhten Arbeitsbelastung unerwünscht. –