2009-05-16 10 views
2

Je crée une application .NET 3.5 avec un formulaire qui dessine un fond noir partiellement transparent. Je suis primordial OnPaintBackground d'y arriver:Transparence partielle avec 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); 
    } 
} 

Il fonctionne, mais parfois la forme tire sur elle-même sans effacer l'écran, ce qui rend la transparence plus sombre que ce qu'elle devrait être. J'ai essayé de jouer avec Graphics.Flush() et Graphics.Clear(), mais cela n'aide pas ou supprime complètement la transparence. Aucune suggestion?

Edit: est ici à quoi il ressemble, après avoir commencé l'application sur la gauche, et après la forme elle-même redessine quelques fois (en réponse à tabulant d'un contrôle à l'autre) à droite:

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

Edit 2: J'ai essayé quelques petites choses ce matin et a remarqué que lorsque le bureau derrière les parties transparentes changer, il est pas vraiment être redessinée. Par exemple, si j'ouvre le Gestionnaire des tâches et le place derrière la fenêtre, vous ne le voyez pas se rafraîchir. Cela a du sens avec ce que j'ai vu avec les niveaux de transparence. Y at-il une fonction pour que Windows redessine la zone derrière votre fenêtre?

Edit 3: J'ai essayé de changer quelques propriétés sur la forme, mais ils sont tous résultat sous la forme de dessin non transparent noir:

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

Je vais essayer de créer un fenêtre séparée pour la partie transparente comme overslacked mentionné, mais d'autres idées sont toujours les bienvenus.

+0

Est-ce une situation dans laquelle vous ne parvenez pas à définir la propriété Opacité? – Demi

+0

Oui, je ne veux pas que les contrôles du formulaire soient transparents, juste des parties de l'arrière-plan de la fenêtre. –

+0

Est-ce sur Vista avec Aero activé? Il serait utile de savoir si je peux essayer moi-même pour essayer de le comprendre. –

Répondre

3

Je pense que j'appellerais ce comportement attendu, en fait. Ce que je ferais est de rendre mon arrière-plan à un bitmap en mémoire et, dans l'événement paint, copiez-le dans le formulaire (double-buffering basique).

Si je suis loin de la base, pourriez-vous poster une capture d'écran? Je ne sais pas si j'imagine ce que vous décrivez correctement.

EDIT:

Je me demande au sujet de votre utilisation de OnPaintBackground ... pre-.NET, si vous vous faites une double mémoire tampon attraperais et ignorer le message WM_ERASKBKGND (pour éviter le scintillement), rendre votre image vers un tampon hors écran, et copiez du tampon à l'écran sur WM_PAINT. Alors, essayez de passer de OnPaintBackground à OnPaint.

Je n'ai pas trop fait de ce genre de chose dans .NET, mais j'avais déjà une bonne idée dessus; Je ne sais pas si ça va bien se traduire ou pas!

EDIT 2:

Marc, plus je pense à ce que vous essayez de faire, plus de problèmes apparaissent. J'allais suggérer de créer un fil de fond dédié à la capture de l'écran et à son rendu sombre; Cependant, afin de supprimer votre propre formulaire, vous devez définir la visibilité sur false, ce qui créerait d'autres problèmes ....

Si vous ne voulez pas abandonner, je vous suggère de créer deux fenêtres et de les "lier" ensemble. Créez une fenêtre semi-opaque (en définissant l'opacité) pour votre fenêtre d'arrière-plan et créez une deuxième fenêtre "normale" pour le premier plan. Utilisez SetWindowRgn sur la fenêtre de premier plan pour couper l'arrière-plan et les positionner les uns sur les autres.

Bonne chance!

+0

Je l'ai essayé (créé un nouveau bitmap, créé un graphique à partir de l'image, l'ai rempli de la même manière que ci-dessus et l'ai dessiné à l'écran en utilisant les graphismes de l'événement paint). Ce n'est pas une mauvaise idée, y a-t-il un autre moyen de dessiner l'image à l'écran que je pourrais essayer? –

+0

J'ai mis à jour ma réponse avec quelque chose d'autre à essayer; Si vous avez un code que vous pouvez envoyer, c'est le même nom d'utilisateur chez gmail et je verrai si je peux vous aider. – overslacked

+0

Merci, je vais essayer l'option double fenêtre et voir si je ne peux pas faire ce travail. –

1

Est-ce que Graphics.CompositingMode est défini sur CompositingMode.SourceCopy? Cela devrait faire en sorte que peindre l'arrière-plan deux fois équivaut à le peindre une fois, car il remplacera les données alpha/couleur existantes plutôt que de les composer.

+0

Bonne suggestion, mais quand je le mets à SourceCopy, il tue toute transparence et dessine juste un fond noir opaque. –

+1

Je ne suis pas certain qu'il existe un moyen d'obtenir le comportement que vous désirez avec WinForms pur. Vous pouvez utiliser P/Invoke pour accéder directement aux API de fenêtre en couches et définir une transparence alpha par pixel pour votre fenêtre, mais je ne suis pas sûr que cela en vaille la peine. Avez-vous envisagé d'utiliser TransparencyKey pour afficher les parties non-UI de votre formulaire, puis de placer une fenêtre partiellement opaque derrière pour créer l'effet souhaité? –