Transparente PictureBox über mehrere Steuerelemente legen

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Transparente PictureBox über mehrere Steuerelemente legen

    Hallo zusammen!

    Ich habe eine transparente PictureBox mit einem teilweise transparentem Bild.
    Mit dieser möchte ich ein Panel abdecken, dass mehrere Steuerelemente beinhaltet.
    Das Problem ist, dass ich immer nur ein Steuerelement als Parent für die Pic-Box
    einstellen kann und somit nicht mehrere darunter zu sehen sein können.

    Gibt es eine Möglichkeit, dass die PictureBox alles durchlässt was darunter liegt,
    oder zumindenst mehr als nur ein Steuerelement?

    Danke im Voraus.
    Error 404: Signature not found!
    Ich versteh das Problem nicht ganz. Wenn die PicBox über dem Panel liegt, dann ist der Container der PicBox (normalerweise) das Form. Und überdeckt somit Panel und dessen Inhalt. Hm. Zeig mal bitte, wie es momentan bei Dir aussieht. Screenshot-Upload per [Erweiterte Antwort] wäre gut.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Willkommen im Forum. :thumbup:

    Pro-grammer schrieb:

    und somit nicht mehrere darunter zu sehen sein können.
    Pack diese Controls in ein Panel und nimm dieses Panel als Parent.
    Jedoch:
    Welchem Zweck dient diese Übung?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo!

    RodFromGermany schrieb:

    Pack diese Controls in ein Panel und nimm dieses Panel als Parent.

    Die Controls sind bereits in einem Panel und das Panel ist als Parent für die Pic-Box eingestellt.
    Jedoch sehe ich unter dem Bild nur die Hintergrundfarbe des Panels.

    VaporiZed schrieb:

    Ich versteh das Problem nicht ganz.

    Die PicBox soll ja auch Panel und Inhalt überdecken, nur möchte ich diese darunter noch sehen.

    @BlackNova Deine Idee funzt leider auch nicht. Hab das jetzt so verstanden, dass ich den Transparency-Key der Form1 z.B. auf grün stelle,
    und die BackColor der PicBox auf die selbe Farbe. Ist das richtig?
    Bilder
    • Screenshot1.png

      51,84 kB, 854×613, 185 mal angesehen
    • Screenshot2.png

      46,33 kB, 854×609, 145 mal angesehen
    Error 404: Signature not found!
    Mach dir ein CustomPictureBox-Control mit folgendem Code, damit wird Hintergrund transparent.

    VB.NET-Quellcode

    1. <System.Diagnostics.DebuggerStepThrough()> _
    2. Public Class TransparentPicturebox
    3. Inherits PictureBox
    4. Public Sub New()
    5. Me.SetStyle(ControlStyles.Opaque, True)
    6. Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
    7. End Sub
    8. Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
    9. Get
    10. Dim cp As CreateParams = MyBase.CreateParams
    11. cp.ExStyle = cp.ExStyle Or &H20 ' Turn on WS_EX_TRANSPARENT
    12. Return cp
    13. End Get
    14. End Property
    15. End Class

    Pro-grammer schrieb:

    Jedoch sehe ich unter dem Bild nur die Hintergrundfarbe des Panels.
    Vielleicht postest Du mal ein Bild posten wie es ist und wie es sein soll?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @HenryV Vielen Dank, an sich funktioniert es.

    Ich verstehe nur leider den Code nicht so ganz.
    Hier mal eine kleine Auflistung:

    1. Wofür ist die erste Zeile?

    VB.NET-Quellcode

    1. <System.Diagnostics.DebuggerStepThrough()> _


    2. Warum hat der Sub

    VB.NET-Quellcode

    1. Public Sub New()
    keinen Namen bzw. wo wird darauf verwiwsen?

    3.

    VB.NET-Quellcode

    1. Me.SetStyle(ControlStyles.Opaque, True)
    bedeutet doch, dass das Control nicht transparent gezeichnet wird?

    4.

    VB.NET-Quellcode

    1. Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
    Wofür ist diese Zeile?

    5. Mit dem letzten Teil kann ich leider garnichts anfangen :(

    VB.NET-Quellcode

    1. Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
    2. Get
    3. Dim cp As CreateParams = MyBase.CreateParams
    4. cp.ExStyle = cp.ExStyle Or &H20 ' Turn on WS_EX_TRANSPARENT
    5. Return cp
    6. End Get
    7. End Property


    Hab auch ein bisschen gegooglet zB. nach einzelnen Befehlen, aber nicht viel Hilfreiches gefunden.

    Außerdem gibt es noch ein Problem:
    Wenn ich das Bild während der Laufzeit im Nachhinein ändern möchte,
    überlagert das neue Bild das alte, anstatt es zu ersetzen.

    Hoffe mir kann da jemand weiterhelfen.
    Error 404: Signature not found!
    @Pro-grammer
    1. DebuggerStepThrough => Debugger Step Through, lesen und verstehen.
    2. Das ist der Konstruktor.
    3. Ausprobieren.
    4. DoubleBuffered macht ein flüssigeres Zeichnen an der GUI.
    5. Das ist eine Prozedur, die von einem sehr tiefen Windows-Level aus aufgferufen wird, wo der Style des zu erstellenden Fensters festgelegt wird.

    Pro-grammer schrieb:

    überlagert das neue Bild das alte, anstatt es zu ersetzen
    Mit welchem Code?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Pro-grammer schrieb:

    Wenn ich das Bild während der Laufzeit im Nachhinein ändern möchte, überlagert das neue Bild das alte, anstatt es zu ersetzen.
    Nicht ganz trivial, aber so geht es...
    Spoiler anzeigen

    VB.NET-Quellcode

    1. <System.Diagnostics.DebuggerStepThrough()> _
    2. Public Class TransparentPicturebox
    3. Inherits PictureBox
    4. Public Sub New()
    5. Me.SetStyle(ControlStyles.Opaque, True)
    6. Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
    7. End Sub
    8. Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
    9. Get
    10. Dim cp As CreateParams = MyBase.CreateParams
    11. cp.ExStyle = cp.ExStyle Or &H20 ' Turn on WS_EX_TRANSPARENT
    12. Return cp
    13. End Get
    14. End Property
    15. Protected Overrides Sub OnPaint(e As PaintEventArgs)
    16. If _image IsNot Nothing Then
    17. e.Graphics.DrawImage(_image, ImageRectangleFromSizeMode(SizeMode))
    18. End If
    19. End Sub
    20. Protected Overrides Sub OnPaintBackground(e As PaintEventArgs)
    21. End Sub
    22. Private _image As Image = Nothing
    23. Public Overloads Property Image() As Image
    24. Get
    25. Return _image
    26. End Get
    27. Set(value As Image)
    28. _image = value
    29. MyBase.RecreateHandle()
    30. End Set
    31. End Property
    32. Private Function DeflateRect(rect As Rectangle, padding As Padding) As Rectangle
    33. rect.X += padding.Left
    34. rect.Y += padding.Top
    35. rect.Width -= padding.Horizontal
    36. rect.Height -= padding.Vertical
    37. Return rect
    38. End Function
    39. Private Function ImageRectangleFromSizeMode(mode As PictureBoxSizeMode) As Rectangle
    40. Dim result As Rectangle = DeflateRect(ClientRectangle, Padding)
    41. If _image IsNot Nothing Then
    42. Select Case mode
    43. Case PictureBoxSizeMode.Normal, PictureBoxSizeMode.AutoSize
    44. ' Use image's size rather than client size.
    45. result.Size = _image.Size
    46. Exit Select
    47. Case PictureBoxSizeMode.StretchImage
    48. ' Do nothing, was initialized to the available dimensions.
    49. Exit Select
    50. Case PictureBoxSizeMode.CenterImage
    51. ' Center within the available space.
    52. result.X = CInt(result.X + ((result.Width - _image.Width) / 2))
    53. result.Y = CInt(result.Y + ((result.Height - _image.Height) / 2))
    54. result.Size = _image.Size
    55. Exit Select
    56. Case PictureBoxSizeMode.Zoom
    57. Dim imageSize As Size = _image.Size
    58. Dim ratio As Single = Math.Min(CSng(ClientRectangle.Width) / CSng(imageSize.Width), CSng(ClientRectangle.Height) / CSng(imageSize.Height))
    59. result.Width = CInt(imageSize.Width * ratio)
    60. result.Height = CInt(imageSize.Height * ratio)
    61. result.X = CInt((ClientRectangle.Width - result.Width) / 2)
    62. result.Y = CInt((ClientRectangle.Height - result.Height) / 2)
    63. Exit Select
    64. Case Else
    65. Exit Select
    66. End Select
    67. End If
    68. Return result
    69. End Function
    70. End Class

    HenryV schrieb:

    VB.NET-Quellcode

    1. result.X = CInt(result.X + ((result.Width - _image.Width) / 2))
    Und das geht mit Integer-Division so;

    VB.NET-Quellcode

    1. result.X = result.X + (result.Width - _image.Width) \ 2
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!