2009-08-05 6 views
4

Ich werde in einem Panel PictureBox überlappt angezeigt, weil jede PictureBox als eine Schicht verwendet wird. Beim ersten Mal wird eine PictureBox definiert und zum Panel hinzugefügt. Die Hintergrundfarbe ist transparent und die Bilder sind leer.Transparenzproblem durch Überlappung PictureBox's bei C#

Das Problem ist, die untere Schicht kann nicht gesehen werden, das transparente Bild, zeigt die Panel Boden. Ausgenommen ist, dass das untere Bild PictureBox zu sehen ist.

Ich habe es mit anderen Kontrollen wie Etikett versucht. Das Problem kann nicht gelöst werden :(

Dank.

+0

Dies ist ein wenig schwer zu folgen. Ich denke, wenn Sie es anders erklären, können Sie einige Antworten bekommen. –

Antwort

11

Dies liegt daran, wenn ich mich richtig erinnere, eine Hintergrundfarbe der Transparent-Einstellung (der tatsächliche Wert null ist, nicht wahr?) Ist nicht wirklich transparent Was Windows tut, ist, dass es die Hintergrundfarbe des übergeordneten Containers des Steuerelements anschaut und die Hintergrundfarbe des Steuerelements darauf einstellt.

Sie können dies vor allem mit Panels sehen. Ohne Inhalt sollten Panels, die auf Transparent gesetzt sind, Sie dahinter sehen lassen, richtig? Falsch. Wenn Sie ein Panel auf eine Reihe von, sagen wir, Textfeldsteuerelementen setzen und das Panel auf Transparent setzen, können Sie nicht sehen e die Textfelder dahinter.

Um echte Transparenz zu erhalten, müssen Sie OnPaintBackground für das fragliche Steuerelement überladen und im Prinzip absolut nichts tun (Rufen Sie den base.OnPainBackground nicht auf!) ... Es gibt mehr als das, wahrscheinlich, aber hier ist ein Beispiel für eine funktionierende TransparentPanel Kontrolle übernehmen wir hier verwenden:

public class TransparentPanel : System.Windows.Forms.Panel 
{ 
    [Browsable(false)] 
    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x20; 
      return cp; 
     } 
    } 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     // Do Nothing 
    } 
} 

wir haben diese Klasse verwendet haben erfolgreich wirklich transparente Platten in der vergangenen Windows Forms-Anwendungen zu erstellen. Wir haben es als Hack verwendet, um das Problem zu beheben, dass das Kontextmenü "Rechtsklick-Kontextmenü über Schaltflächen" erscheint.

+0

Wie kann ich das nennen, um ein transparentes Panel in Winforms – user335160

+0

zu erstellen Sie können die obige Klasse in ein Steuerelement Bibliothek Projekt, das Sie verweisen (das ist was wir tun) oder Sie können es auch in Ihrem Projekt direkt als .cs Datei. Es wird jedoch nicht in Ihrer Toolbox angezeigt, wenn Sie es nicht hinzufügen.Dennoch können Sie ein normales Panel in Ihren Designbereich ziehen und die Datei designer.cs öffnen und das Objekt manuell in Ihr spezielles TransparentPanel ändern. –

+1

öffentliche Konstante int WS_EX_TRANSPARENT = 0x20; cp.ExStyle | = WS_EX_TRANSPARENT; – Hbas

5

Dies ist mein nehmen auf sie:

class TransPictureBox : Control 
{ 
    private Image _image = null; 

    public Image Image 
    { 
     get 
     { 
      return _image; 
     } 
     set 
     { 
      _image = value; 
     } 
    } 
    public TransPictureBox() 
    { 
    } 

    protected override void OnPaintBackground(PaintEventArgs pevent) 
    { 
    } 

    protected override void OnPaint(PaintEventArgs pe) 
    { 
     if(Image != null) 
      pe.Graphics.DrawImage(Image, 0, 0); 
    } 
    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x20; 
      return cp; 
     } 
    } 
} 

Sie sollten für die Positionierung des Bildes etwas mehr Logik hinzufügen, wie Sie die OnPaint-Methode entsprechend wollen und bearbeiten.

0

Sie sollten Ihr Bild wird nicht

2

streched werden ich habe in der Lage, dies zu tun in VB

pe.Graphics.DrawImage(Image, 0, 0, Image.Width, Image.Height); 

tun. Es gibt jedoch ein paar Tricks. Zuallererst müssen Sie die Bildfelder einander hinzufügen. Zweitens müssen die Bilder in den Bildfeldern PNGs sein.

Für diese App musste ich 3 verschiedene Ebenen auf einer Hintergrundebene anzeigen und sie mit Checkboxen ein- und ausschalten. Wenn es nicht funktioniert, spielen Sie damit, wie Sie Ihre PNGs speichern, es ist ziemlich pingelig.

Imports System.Drawing 
Imports System.Drawing.Imaging 
Imports System 

Public Class Form1 

    Dim MarkerBox1 As New PictureBox 
    Dim MarkerBox2 As New PictureBox 
    Dim MarkerBox3 As New PictureBox 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     PictureBox1.Image = New Bitmap("C:\BackGround.bmp") 

     MarkerBox1.Image = New Bitmap("C:\TestOverlay1.png") 
     MarkerBox1.BackColor = System.Drawing.Color.Transparent 
     MarkerBox1.Visible = True 
     MarkerBox1.SizeMode = PictureBoxSizeMode.AutoSize 
     PictureBox1.Controls.Add(MarkerBox1) 

     MarkerBox2.Image = New Bitmap("C:\TestOverlay2.png") 
     MarkerBox2.BackColor = System.Drawing.Color.Transparent 
     MarkerBox2.Visible = True 
     MarkerBox2.SizeMode = PictureBoxSizeMode.AutoSize 
     MarkerBox1.Controls.Add(MarkerBox2) 

     MarkerBox3.Image = New Bitmap("C:\TestOverlay3.png") 
     MarkerBox3.BackColor = System.Drawing.Color.Transparent 
     MarkerBox3.Visible = True 
     MarkerBox3.SizeMode = PictureBoxSizeMode.AutoSize 
     MarkerBox2.Controls.Add(MarkerBox3) 


    End Sub 

    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged 
     If CheckBox1.Checked Then 
      MarkerBox1.Visible = True 
     Else 
      MarkerBox1.Visible = False 
     End If 
     Visibilitychanged() 
    End Sub 

    Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged 
     If CheckBox2.Checked Then 
      MarkerBox2.Visible = True 
     Else 
      MarkerBox2.Visible = False 
     End If 
     Visibilitychanged() 
    End Sub 

    Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged 
     If CheckBox3.Checked Then 
      MarkerBox3.Visible = True 
     Else 
      MarkerBox3.Visible = False 
     End If 
     Visibilitychanged() 
    End Sub 

    Private Sub Visibilitychanged() 

     PictureBox1.Controls.Clear() 
     MarkerBox1.Controls.Clear() 
     MarkerBox2.Controls.Clear() 
     MarkerBox3.Controls.Clear() 

     Dim PB As PictureBox = PictureBox1 
     If MarkerBox1.Visible Then 
      PB.Controls.Add(MarkerBox1) 
      PB = MarkerBox1 
     End If 
     If MarkerBox2.Visible Then 
      PB.Controls.Add(MarkerBox2) 
      PB = MarkerBox2 
     End If 
     If MarkerBox3.Visible Then 
      PB.Controls.Add(MarkerBox3) 
      PB = MarkerBox3 
     End If 

    End Sub 
+0

Heiss verdammt, das funktioniert tatsächlich! Beachten Sie jedoch, dass PictureBoxSizeMode.Zoom ** nicht funktioniert ** und Sie möglicherweise die Dimensionen der untergeordneten PictureBoxes manuell festlegen müssen, wenn das Basisimage auf einen übergeordneten Container skaliert werden darf. –