2009-05-16 14 views
2

Ich mache eine .NET 3.5 App mit einem Formular, das einen teilweise transparenten schwarzen Hintergrund zeichnet. Ich zwingende OnPaintBackground dies zu erreichen:Teiltransparenz mit C# .NET 3.5 WinForms?

protected override void OnPaintBackground(PaintEventArgs e) 
{ 
    using (Brush brush = new SolidBrush(Color.FromArgb(155, Color.Black))) 
    { 
     e.Graphics.FillRectangle(brush, e.ClipRectangle); 
    } 
} 

Es funktioniert, aber gelegentlich die Form zieht über sich selbst, ohne den Bildschirm zu löschen, so dass die Transparenz dunkler als es sein sollte. Ich habe versucht, mit Graphics.Flush() und Graphics.Clear() zu spielen, aber es hilft entweder nicht oder entfernt vollständig Transparenz. Irgendwelche Vorschläge?

Edit: Hier ist, wie es aussieht, nachdem die App auf der linken Seite beginnen, und nach der Form neu zeichnet sich ein paar Mal (als Antwort von einem Steuerelement zu einem anderen zu Tabbing) auf der rechten Seite:

Transparency Issue http://www.quicksnapper.com/files/5085/17725729384A10347269148_m.png

Edit 2: ich war heute Morgen ein paar Dinge heraus versucht und festgestellt, dass, wenn der Desktop hinter den transparenten Bereichen ändern, es ist nicht wirklich neu gezeichnet zu sein. Wenn ich zum Beispiel den Task-Manager öffne und ihn hinter das Fenster halte, sieht er nicht, dass er sich selbst aktualisiert. Dies macht Sinn mit dem, was ich mit den Transparenzstufen gesehen habe. Gibt es eine Funktion, Windows dazu zu bringen, den Bereich hinter dem Fenster neu zu zeichnen?

bearbeiten 3: Ich habe versucht, ein paar Eigenschaften auf dem Formular zu ändern, aber sie alle Ergebnis in der Form Zeichnung nicht-transparent schwarz:

this.AllowTransparency = true; 
this.DoubleBuffered = true; 
this.Opacity = .99; 

Ich werde versuchen, eine zu schaffen separates Fenster für den transparenten Teil als übertönt erwähnt, aber andere Ideen sind immer noch willkommen.

+0

Ist dies eine Situation, in der Sie die Opacity-Eigenschaft nicht festlegen können? – Demi

+0

Ja, ich möchte nicht, dass die Steuerelemente des Formulars transparent sind, nur Teile des Fensterhintergrunds. –

+0

Ist dies auf Vista mit Aero aktiviert? Es wäre nützlich zu wissen, dass ich es selbst ausprobieren kann, um es herauszufinden. –

Antwort

3

Ich denke, ich würde dieses erwartete Verhalten tatsächlich nennen. Was ich tun würde ist, meinen Hintergrund auf eine In-Memory-Bitmap zu rendern und diese in das Paint-Ereignis in das Formular zu kopieren (grundlegende Doppelpufferung).

Wenn ich weit weg bin, könnten Sie einen Screenshot hochladen? Ich weiß nicht, dass ich mir vorstelle, was du richtig schilderst.

EDIT:

Ich frage mich, über Ihre Benutzung OnPaintBackground ... pre-.NET, wenn Sie Double-Buffering taten würden Sie die WM_ERASKBKGND Nachricht fangen und ignorieren (Flimmern verhindern), machen Ihr Bild in einen Offscreen-Puffer kopieren und aus dem Puffer auf den Bildschirm von WM_PAINT kopieren. Versuchen Sie also, von OnPaintBackground zu OnPaint zu wechseln.

Ich habe nicht so viel in .NET gemacht, aber ich hatte einen ziemlich guten Griff davor; Ich weiß nur nicht, ob es gut übersetzt oder nicht!

EDIT 2:

Marc, je mehr ich über das, was Sie versuchen zu tun, werden die Probleme mehr. Ich würde vorschlagen, einen Hintergrund-Thread zu erstellen, der dazu dient, den Bildschirm zu erfassen und ihn zu verdunkeln. Um jedoch Ihr eigenes Formular zu entfernen, müssen Sie die Sichtbarkeit auf "false" setzen, was zu anderen Problemen führen würde ....

Wenn Sie nicht aufgeben wollen, würde ich vorschlagen, zwei Fenster zu erstellen und sie miteinander zu verbinden. Erstellen Sie ein halbdeckendes Fenster (indem Sie Deckkraft einstellen) für Ihr Hintergrundfenster und erstellen Sie ein zweites "normales" Fenster für den Vordergrund. Verwenden Sie SetWindowRgn im Vordergrundfenster, um den Hintergrund auszuschneiden und sie übereinander zu positionieren.

Viel Glück!

+0

Ich habe es versucht (erstellt eine neue Bitmap, erstellt eine Grafik aus dem Bild, füllte es auf die gleiche Weise wie oben, und zeichnete es auf den Bildschirm mit den Grafiken des Malvorgangs) und es hatte das gleiche Problem. Es ist jedoch keine schlechte Idee, gibt es eine andere Möglichkeit, das Bild auf den Bildschirm zu ziehen, den ich ausprobieren könnte? –

+0

Ich habe meine Antwort mit etwas anderem aktualisiert, um es zu versuchen; Wenn Sie einen Code haben, den Sie senden können, ist es der gleiche Benutzername bei Google Mail und ich werde sehen, ob ich Ihnen helfen kann. – overslacked

+0

Danke, ich werde die Doppel-Fenster-Option ausprobieren und sehen, ob ich das nicht machen kann. –

1

Ist Graphics.CompositingMode auf CompositingMode.SourceCopy eingestellt? Das sollte dazu führen, dass der Hintergrund zweimal so gemalt wird, dass er einmal gezeichnet wird, da er die vorhandenen Alpha-/Farbdaten ersetzen wird, anstatt darüber zu komponieren.

+0

Guter Vorschlag, aber wenn ich ihn auf SourceCopy setze, wird jegliche Transparenz gelöscht und nur ein undurchsichtiger schwarzer Hintergrund gezeichnet. –

+1

Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, das gewünschte Verhalten mit reinen WinForms zu erreichen. Sie können P/Invoke verwenden, um direkt auf die APIs mit Ebenenfenstern zuzugreifen und die Alpha-Transparenz pro Pixel für Ihr Fenster festzulegen, aber ich bin mir nicht sicher, ob es sich lohnt. Haben Sie in Betracht gezogen, TransparencyKey zu verwenden, um die Nicht-UI-Teile Ihres Formulars durchscheinen zu lassen, und dann ein teilweise undurchsichtiges Fenster dahinter zu platzieren, um den gewünschten Effekt zu erzielen? –