2009-06-01 6 views
2

Actuellement, j'ai une application Winforms qui repose sur des effets de transparence. Cependant, cela s'avère être une douleur absolue dans le préverial derrière! Winforms comme Im learning ne traite pas particulièrement bien de la transparence. Je me demandais si cela serait plus facile d'utiliser les composants WPF pour le bit de transparence et les winforms pour le reste (notez bien que l'idée de déplacer toute l'application sur WPF n'est pas faisable!). Je ne sais rien à propos de WPF, d'où la raison pour laquelle je suis ici! Ce que je considérais était:C# Winforms-WPF interop

1) Héberger un composant WPF dans un contrôle utilisateur Winforms, par ex. Exemple de WPF Control:

<UserControl x:Class="WindowsFormsApplication1.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <Grid> 
     <Rectangle Name="rectangle1" Stroke="White" Fill="Black" RadiusX="10" RadiusY="10" Opacity="0.7" /> 
     <Rectangle Margin="57,101,43,99" Name="dialog" Stroke="Gray" Fill="White" RadiusX="10" RadiusY="10" /> 
    </Grid> 
</UserControl> 

2) hôte d'une commande d'utilisateur Winforms (contenu) dans le rectangle blanc (dialogue) du contrôle WPF. 3) autoriser le contenu (contrôle utilisateur Winforms) à appeler du code sur le parent du contrôle WPF.

Tout d'abord ...

  • Est-ce une chose raisonnable à faire ou suis-je aboiements le mauvais arbre?
  • Est-ce que cela peut être réalisé plus facilement?
  • Quelqu'un peut-il m'aider ici? (Un exemple de code serait reçu avec gratitude!)
  • Enfin ... y at-il des ressources en ligne qui peuvent m'aider a) apprendre WPF et b) devenir plus autonome?
+1

@TK: La transparence de rendu mélangée avec WPF et Winforms est un problème, et je ne sais pas si celui-ci est résoluble. WPF et WinForms sont fondamentalement différents, et je me souviens avoir lu quelque part que bien qu'ils puissent s'héberger mutuellement, les composants superposés ne seront pas rendus correctement, point final. Ils ont besoin de régions distinctes. Je crois que j'ai lu cela dans le livre d'Adam Nathan, mais je ne l'ai pas ici pour référence, alors je pourrais me souvenir incorrectement. –

+0

@Greg D: Je crois que vous avez absolument raison. Le problème étant que chaque contrôle (que ce soit WPF ou Winforms) nécessite son propre espace aérien. C'est à dire qu'à un moment donné, un pixel sur l'écran est soit un pixel WPF, soit un Winform Pixel et ne peut pas être un hybride des deux.J'ai résolu ce problème en obtenant les composants Winforms à se rendre eux-mêmes en tant que fichier BMP, puis restituer le fichier bmp en tant qu'arrière-plan d'un autre contrôle. Sale ... oui mais ça a l'air de marcher assez bien. –

+0

Approche intelligente. Pouvez-vous poster comment vous avez obtenu les contrôles winforms à rendre en tant que bitmap pour les effets de fusion dans une réponse à votre question? :) Est-ce que vous capturez des changements dans les contrôles de winforms et mettez à jour le bitmap de manière appropriée quand ils se produisent, ou les contrôles de winforms sont-ils statiques pendant les effets de transparence? –

Répondre

1

Voici la solution que j'ai utilisée pour résoudre le problème. Cette solution repose sur le contrôle de superposition pour rendre son parent en tant qu'image bitmap. Cela devient ensuite peint comme l'arrière-plan du contrôle de superposition.

public class OverlayingControl : UserControl 
{ 
    /// <summary> 
    /// Overrides the c# standard Paint Background to allow the custom background to be drawn 
    /// within the OnPaint function 
    /// </summary> 
    /// 
    /// <param name="e">Arguements used within this function</param> 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     //Do Nothing 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     // Render the Parents image to a Bitmap. NB: bitmap dimensions and Parent Bounds can be changed to achieve the desitred effect 
     Bitmap background = new Bitmap(Width, Height, PixelFormat.Format64bppArgb); 
     Parent.DrawToBitmap(background, Parent.Bounds); 

     // Paint background image    
     g.DrawImage(background, 0, 0, new RectangleF(Location, Size), GraphicsUnit.Pixel); 

     // Perform any alpha-blending here by drawing any desired overlay e.g. 
     // g.FillRectangle(new SolidBrush(semiTransparentColor), Bounds); 
    } 

} 

Ceci est réalisé uniquement dans le domaine WinForms, mais je crois qu'il pourrait être possible de transmettre cette image Bitmap à un contrôle WPF pour rendre au besoin. Actuellement, il n'y a pas de disposition pour mettre à jour le bitmap lorsque le parent change. Cependant, il devrait être trivial de créer une méthode personnalisée qui efface le bitmap et redessine le contrôle Overlayng. Je ne réalise pas une solution élégante ... mais cela semble fonctionner assez bien.

4

C'est certainement possible, et je pense que vous avez raison de dire que ce serait la manière la plus simple de travailler avec la transparence.

Je ne l'ai pas essayé moi-même, but according to this article on CodeProject, il devrait être assez simple. Vous devez utiliser le ElementHost control pour héberger votre contenu WPF.

L'hébergement de WPF dans un contrôle WinForms est un scénario pris en charge, une fonctionnalité intégrée à l'infrastructure. Donc, il ne devrait y avoir aucun problème à le faire. Il y a aussi un composant WPF pour aller dans l'autre sens, hébergeant WinForms dans une application WPF.

+0

Merci pour le lien ... c'est vraiment aidé! Le seul problème maintenant est de rendre le WPF pour rendre sa transparence pour montrer les contrôles Winforms en dessous! À l'heure actuelle, il est complètement opaque en ce moment –

Questions connexes