none
WPF Probleme bei WindowTranzparenz und einbinden einer UserControl RRS feed

  • Frage

  • Hallo Leute,

    also ich binde in meine WPF Anwendung ein WinForm UserControl ein ( brauche ich, da ich ZedGraph benutzen will) in etwa so:

    WindowsFormsHost host = new WindowsFormsHost();
          graph = new Equalizer(this);
          host.Child = graph;
          EQGrid.Children.Add(host);
    

    aber gleichzeitig soll mein Fenster keinen Rahmen haben und der Rand durchsichtig sein:

    <Window x:Class="SAT3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SAT3"
        Title="SAT3" Height="730" Width="682"
        AllowsTransparency="True" WindowStyle="None" Background="Transparent"
        Loaded="Window_Loaded">
    

    leider verschwindet die UserControl/der WinFormsHost wenn ich die Transparenz erlaube, weiß jemand einen ausweg?

    Vielen Dank schoneinmal.

     

    Gruß B

    Mittwoch, 25. August 2010 21:49

Antworten

  • Falls du Aero von Vista oder Windows 7 nutzen kannst, wäre es möglich, dein Fenster durchsichtig zu machen, der Content im Fenster bleibt jedoch sichtbar.

     

    Erstelle folgende Klasse in deinem Projekt :

    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.Windows.Media
    Imports System.Windows
    Imports System.Windows.Interop
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Runtime.InteropServices
    
    Public Class _GlassHelper
      Public Shared Function ExtendGlassFrame(ByVal window As Window, ByVal margin As Thickness) As Boolean
        If Not DwmIsCompositionEnabled() Then
          Return False
        End If
    
        Dim hwnd As IntPtr = New WindowInteropHelper(window).Handle
        If hwnd = IntPtr.Zero Then
          Throw New InvalidOperationException("The Window must be shown before extending glass.")
        End If
    
        ' Set the background to transparent from both the WPF and Win32 perspectives
        window.Background = System.Windows.Media.Brushes.Transparent
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent
    
        Dim margins As New MARGINS(margin)
        DwmExtendFrameIntoClientArea(hwnd, margins)
        Return True
      End Function
    
      <DllImport("dwmapi.dll", PreserveSig:=False)> _
      Private Shared Sub DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef margins As MARGINS)
      End Sub
    
      <DllImport("dwmapi.dll", PreserveSig:=False)> _
      Private Shared Function DwmIsCompositionEnabled() As Boolean
      End Function
    End Class
    
    Structure MARGINS
      Public Sub New(ByVal t As Thickness)
        Left = CInt(t.Left)
        Right = CInt(t.Right)
        Top = CInt(t.Top)
        Bottom = CInt(t.Bottom)
      End Sub
      Public Left As Integer
      Public Right As Integer
      Public Top As Integer
      Public Bottom As Integer
    End Structure
    

    Nun rufst du im Window_Loaded Event folgende Befehlszeile auf :

    _GlassHelper.ExtendGlassFrame(Me, New Thickness(-1))
    

    Nun ist das Fenster durchsichtig, jedoch der Inhalt sichtbar ;)

    Vielleicht hilft dir das weiter :)

    Freundliche Grüße

    • Als Antwort markiert BtheBeast Donnerstag, 26. August 2010 15:24
    Donnerstag, 26. August 2010 09:51
  • Hallo B.,

    siehe den Community-Zusatz (unten) bei:

    [WindowsFormsHost Class (System.Windows.Forms.Integration)]
    http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.windowsformshost(VS.85).aspx

           "Be aware that when trying to use a WindowsFormsHost with a Forms control 
            (from Microsoft or other party) is a WPF Window using AllowsTransparency=true,
            the control will never show up"


    mit AllowsTransparency gibt es momentan ebenfalls ein paar offene Punkte:

    [Produkt-Suchergebnisse | Microsoft Connect]
    http://connect.microsoft.com/VisualStudio/SearchResults.aspx?SearchQuery=AllowsTransparency

    Auserdem müsste man ja seine App auf "WindowStyle.None" setzen etc.

    Ohne AllowsTransparency sollte aber zumindest eine Transparenz eines im WindowsFormsHost dargestellten Controls etwa gegen eine WPF-BackColor eines Grids funktionieren. 


    ciao Frank
    • Als Antwort markiert BtheBeast Donnerstag, 26. August 2010 15:22
    Donnerstag, 26. August 2010 06:04

Alle Antworten

  • Hallo B.,

    siehe den Community-Zusatz (unten) bei:

    [WindowsFormsHost Class (System.Windows.Forms.Integration)]
    http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.windowsformshost(VS.85).aspx

           "Be aware that when trying to use a WindowsFormsHost with a Forms control 
            (from Microsoft or other party) is a WPF Window using AllowsTransparency=true,
            the control will never show up"


    mit AllowsTransparency gibt es momentan ebenfalls ein paar offene Punkte:

    [Produkt-Suchergebnisse | Microsoft Connect]
    http://connect.microsoft.com/VisualStudio/SearchResults.aspx?SearchQuery=AllowsTransparency

    Auserdem müsste man ja seine App auf "WindowStyle.None" setzen etc.

    Ohne AllowsTransparency sollte aber zumindest eine Transparenz eines im WindowsFormsHost dargestellten Controls etwa gegen eine WPF-BackColor eines Grids funktionieren. 


    ciao Frank
    • Als Antwort markiert BtheBeast Donnerstag, 26. August 2010 15:22
    Donnerstag, 26. August 2010 06:04
  • Vielen Dank für die schnelle und ausführliche Antwort.

    Eine andere Möglichkeit ist wahrscheinlich nicht bekannt wie man die "Windowränder"  wegbekommt, oder? WindowsStyle steht ja schon auf None.

     

    Gruß B

    Donnerstag, 26. August 2010 07:46
  • Falls du Aero von Vista oder Windows 7 nutzen kannst, wäre es möglich, dein Fenster durchsichtig zu machen, der Content im Fenster bleibt jedoch sichtbar.

     

    Erstelle folgende Klasse in deinem Projekt :

    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.Windows.Media
    Imports System.Windows
    Imports System.Windows.Interop
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Runtime.InteropServices
    
    Public Class _GlassHelper
      Public Shared Function ExtendGlassFrame(ByVal window As Window, ByVal margin As Thickness) As Boolean
        If Not DwmIsCompositionEnabled() Then
          Return False
        End If
    
        Dim hwnd As IntPtr = New WindowInteropHelper(window).Handle
        If hwnd = IntPtr.Zero Then
          Throw New InvalidOperationException("The Window must be shown before extending glass.")
        End If
    
        ' Set the background to transparent from both the WPF and Win32 perspectives
        window.Background = System.Windows.Media.Brushes.Transparent
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent
    
        Dim margins As New MARGINS(margin)
        DwmExtendFrameIntoClientArea(hwnd, margins)
        Return True
      End Function
    
      <DllImport("dwmapi.dll", PreserveSig:=False)> _
      Private Shared Sub DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef margins As MARGINS)
      End Sub
    
      <DllImport("dwmapi.dll", PreserveSig:=False)> _
      Private Shared Function DwmIsCompositionEnabled() As Boolean
      End Function
    End Class
    
    Structure MARGINS
      Public Sub New(ByVal t As Thickness)
        Left = CInt(t.Left)
        Right = CInt(t.Right)
        Top = CInt(t.Top)
        Bottom = CInt(t.Bottom)
      End Sub
      Public Left As Integer
      Public Right As Integer
      Public Top As Integer
      Public Bottom As Integer
    End Structure
    

    Nun rufst du im Window_Loaded Event folgende Befehlszeile auf :

    _GlassHelper.ExtendGlassFrame(Me, New Thickness(-1))
    

    Nun ist das Fenster durchsichtig, jedoch der Inhalt sichtbar ;)

    Vielleicht hilft dir das weiter :)

    Freundliche Grüße

    • Als Antwort markiert BtheBeast Donnerstag, 26. August 2010 15:24
    Donnerstag, 26. August 2010 09:51
  • Oh sehr cool, vielen Dank!

    Das geht allerdings dann nur unter Vista und 7 oder? Xp unterstützt das nicht?

    Gruß B

    Donnerstag, 26. August 2010 10:00
  • Eventuell ist es möglich unter XP mit dem Programm Vystal einen Aero Effekt zu erlangen, ob es aber die richtigen DLL´s mitbringt, darüber weiß ich leider nichts. Muss mich selbst erst mit dem Problem beschäftigen.

    Hier ein kleines Walkthrough

    Müsstest du ausprobieren, ob es mit diesem Programm dann unter XP auch funktioniert.

    Vystal ist ein Freeware - Programm : Download hier

    Sg

    Donnerstag, 26. August 2010 10:10
  • nein, erst ab Vista.

     


    ciao Frank
    Donnerstag, 26. August 2010 10:12
  • Hallo B.,

        > Vielen Dank für die schnelle und ausführliche Antwort.

    gern.



        > Eine andere Möglichkeit ist wahrscheinlich nicht bekannt
        > wie man die "Windowränder"  wegbekommt, oder?
        > WindowsStyle steht ja schon auf None.

    "WindowsStyle.None" ist doch ok. Ich selber empfand das nur als Einschränkung, wenn Du eh randlose Fenster haben willst ... kein Problem. (None wäre ja bei AllowsTransparency erforderlich).

    Vielleicht zunächst dann eine Frage:

    Musst Du wirklich ZedGraph benutzen?
    Es gibt doch mehrere hervoragende WPF Chart Darstellungsmöglichkeiten.
    Welchen Typus von Chart benötigst Du?

    ... und vielleicht noch einmal zu WinForms-UserControl:
    Du könntest dort einfach "Color.FromArgb" benutzen und es wird in WPF mit der angegebenen Transparenz angezeigt. Da sind dann DwmIsCompositionEnabled PInvokes nicht notwendig.


    ciao Frank
    Donnerstag, 26. August 2010 10:19
  • Also zu Zedgraph: ich hab lange gesucht, aber Zedgraph, ist von denen die ich gefunden habe, mit abstand der Beste. Wenn du etwas weißt was es mindestens genauso gut kann, dann würde ich mich freuen.

    Es ist ein richtiger grafischer EQ, mit logaritmischen Axen, mit durch die Maus verschiebbaren Punkten u.s.w

    Hier mal ein Bild meiner Anwendung(damit ihr euch mal ein "Bild" machen könnt ^^), das was ich jetzt mit dem Holz Hintergrund gemacht habe, soll weg: www.beastclaw.de/stuff/sat3.png

    Die UserControl soll ja garnicht durchsichtig werden.

    Gruß B

     

     

    Donnerstag, 26. August 2010 11:13
  • Hallo B.,

    ja ZedGraph ist schon eines der besten von den ~freien. Aber für WinForms wäre das MSChart zum Beispiel ebenso gut und dann eben kein 3rd Party nötig.

    [Downloaddetails: Microsoft Chart Controls für Microsoft .NET Framework 3.5]
    http://www.microsoft.com/downloads/details.aspx?displaylang=de&FamilyID=130f7986-bf49-4fe5-9ca8-910ae6ea442c

    nebst:

    [Samples Environment for Microsoft Chart Controls - Home]
    http://code.msdn.microsoft.com/mschart

    ________________

    Für WPF dann hier:

    [WPF - Release: WPF Toolkit - February 2010 Release]
    http://wpf.codeplex.com/releases/view/40535
    (zwar in Preview quality, aber ggf. reicht es)

    Die Charts sind etwa wie im Silverlight Toolkit 4, hier kann man sich die mal unter DataVisualization (links im Tree) anschauen:

    http://www.silverlight.net/content/samples/sl4/toolkitcontrolsamples/run/default.html

    ___________________

            > das was ich jetzt mit dem Holz Hintergrund gemacht
            > habe, soll weg: [...]

    hmm, also der schwarze Hintergund des Charts soll zum Holz Hintergrund werden?

     

             > Die UserControl soll ja garnicht durchsichtig werden.

    sondern der Hintergrund des Charts?


    ciao Frank
    Donnerstag, 26. August 2010 13:47
  • Wenn ich das richtig verstehe möchte er den Holzhintergrund garnicht haben, dieser Teil sollte Transparent sein. So das sein selbst gemachtes Fenster ohne dem Rand zu sehen ist.

    Leider ist es nicht möglich, WindowsFormsHost und AllowsTransparency="True" gemeinsam zu verwenden, da die WindowsFormsHost Opacity="100" voraussetzt. Zu diesem Problem wurde bereits im Forum ein Thread geöffnet ...

    Du wirst dich wohl oder übel mit den Controls aus der 

    System.Windows.Controls.DataVisualization.Charting
    
    auseinander setzen müssen ...

     

    Donnerstag, 26. August 2010 14:54
  • Spellcaster sieht das richtig.

    Vielen Dank ihr beiden für die Antworten, ich werde mir was überlegen, oder mich mit der Holzoptik anfreunden^^.

    Gruß B

    Donnerstag, 26. August 2010 15:22