2010-08-13 4 views
5

En résumé, j'essaie d'écrire des notifications contextuelles de type toast (similaires à Growl) qui devraient apparaître à côté de la barre d'état système et de la pile, selon le cas.VB.Net WinForms Formulaire OnPaint() Transparency Refresh

Je peux gérer l'instanciation/emplacement/etc ... mais je veux ajouter une capacité pour les toasts non-rectangulaires. J'aimerais aussi avoir la transparence Alpha pour qu'un fond PNG semi-transparent sur le toast se fondre avec le bureau ou les fenêtres derrière.

Alors ... Pour l'évidence de la manière suivante:

Form.TransparencyKey ne suffit pas à mes besoins car il est un effet de transparence tout ou rien que je veux 50/50 de premier plan/arrière-plan Dans certains cas, 0/100 dans d'autres, 100/0 dans d'autres, etc.

Mon approche initiale consiste à remplacer la méthode OnBackgroundPaint(), à commenter l'appel de MyBase.OnBackgroundPaint et à utiliser l'objet graphique dans l'événement dessiner exactement ce que je veux à une forme.

Cela semble fonctionner pour commencer - pour le moment, je dessine juste un rectangle à des fins de test afin qu'un PNG puisse présenter de nouvelles difficultés mais je n'y suis pas encore arrivé. Ce que je n'ai pas réussi à accomplir est la mise à jour du graphique - La première fois que le formulaire est rendu, il montre parfaitement comme je l'attendais (pas de bordure, juste quelques rectangles flottant sur un bureau). Si je déplace les fenêtres derrière la fenêtre transparente, la fenêtre transparente ne met pas à jour/re-paint

Je crois que je dois appeler Me.Invalidate() pour forcer un re-draw mais je ne sais pas quand je devrais faire l'appel - Comment savoir qu'une fenêtre derrière moi a changé de contenu? Est-ce que je prends la mauvaise approche?

Un grand merci

Edit: Je essayé de mettre un Me.Invalidate() à l'intérieur d'une minuterie juste pour tester comment le redessiner arrive - il semble que cela ne déclenche un nouveau tracé mais le redessiner opccurs SUR l'arrière-plan du formulaire existant - c'est-à-dire une zone initialement opaque à 50% est maintenant opaque à 75% (50% + 50% de ce qui existait auparavant)

Donc, après quelques Invalidate() s, ma forme est Montrer comme une boîte noire - Je dois effacer l'arrière-plan du formulaire avant de re-dessiner mais Graphics.Clear (Couleur) semble simplement faire un remplissage avec la couleur spécifiée - et évidemment pour les besoins de cette question, Colors.Tra nsparent ne vraiment signifie transparent - Il semble être une astuce utilisée lors du rendu de la fenêtre pour "montrer le contenu du contrôle en dessous" qui ne fonctionne pas lorsque nous traitons le formulaire lui-même

In cas où quelqu'un veut reproduire facilement, le code de ma forme est ci-dessous:

Imports System.Drawing 
Public Class TransparentForm 

    Private Timer As Timers.Timer 

    Private Sub TransparentForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     Timer = New Timers.Timer 
     AddHandler Timer.Elapsed, AddressOf Timer_Tick 
     Timer.Interval = 100 
     Timer.Start() 
    End Sub 

    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs) 
     ''MyBase.OnPaintBackground(e) 
     Console.WriteLine("BackgroundPainted") 
     For x = 0 To 9 
      e.Graphics.FillRectangle(
       New SolidBrush(Color.FromArgb(CInt(x/10 * 255), 127, 127, 127)), 
       CInt(x * Me.Width/10), 
       0, 
       CInt(Me.Width/10), 
       Me.Height 
      ) 
     Next 
    End Sub 

    Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs) 
     Me.Invalidate() 
    End Sub 

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 
     MyBase.OnPaint(e) 
     Console.WriteLine("Painted") 
    End Sub 

    Protected Overrides Sub OnInvalidated(ByVal e As System.Windows.Forms.InvalidateEventArgs) 
     MyBase.OnInvalidated(e) 
     Console.WriteLine("Invalidated") 
    End Sub 

End Class 
+0

J'ai examiné votre code et j'ai réalisé qu'il dessine le formulaire avec un certain niveau de transparence [partielle]. Cependant, il ne permet pas de cliquer sur les zones "transparentes". La solution fournie par l'article CodeProject vous permet réellement de ** cliquer sur ** les zones transparentes pour sélectionner les fenêtres sous la forme transparente partielle. –

Répondre

1

Il y a un article CodeProject qui montre comment utiliser un .png comme « peau » de la forme. Évidemment, cela supporte la transparence partielle au lieu de l'approche 50/50 offerte par Form.TransparencyKey.

Ceci est le link de l'article codeproject. J'essaye de télécharger le projet dans VB et mettra à jour cette réponse dès que c'est fait.


EDIT

Voici le link à la version VB.NET de l'article CodeProject je citais ci-dessus.
http://www20.zippyshare.com/v/86701716/file.html

Je vais essayer de revoir votre code et voir ce qui peut être fait pour aider votre situation.

+0

En ce qui concerne l'article. Vous devrez supprimer toute image PNG 32 bits sur le formulaire pour afficher le formulaire avec l'image en tant qu'arrière-plan du formulaire. Vous devrez remplacer ce processus en spécifiant un fichier PNG dans votre code si vous souhaitez définir l'arrière-plan du formulaire sur l'image. –

+0

Merci - Et je devrais être en mesure de pirater l'implémentation autour d'un peu. Je vous serais reconnaissant si vous pouviez identifier le problème avec mon code - je vais jeter un oeil à votre code converti. Cela peut me prendre quelques heures pour revenir à vous – Basic

+0

Ok, effet secondaire intéressant - L'utilisation de la technique fournie produit en effet une forme entièrement compatible avec la transparence alpha, cependant, aucun contrôle ou autre élément de l'interface utilisateur n'est affiché. En outre, aucun événement n'est reçu pour les contrôles sur le formulaire. Avez-vous des suggestions? – Basic