Laden...

Transparente Pictureboxes

Letzter Beitrag vor 15 Jahren 16 Posts 2.448 Views
Transparente Pictureboxes

Hallo,

Ich bin gerade daran einem lästigen Problem den Gar aus zu machen.

Es ist nämlich so, dass ich in einer Groupbox mehrere Pictureboxes habe, die aber jeweils nicht voll ausgefüllt sind. Zum Teil verdecken sie sich sogar.

Nun hätte ich aber gerne, dass die Inhalte der unteren Pictureboxes nicht von den oberen verdeckt werden, wenn diese darüber nicht gefüllt sind.

Ich habe schon das Property BackgroundColor auf transparent gesetzt. Mit dieser Einstellung scheint es wirklich transparent zu sein, jedoch ist es nicht der Fall. Denn es wird lediglich die Farbe der Groupbox als Hintergrund benutzt. Und somit werden wieder die darunterliegenden PicBoxes überdeckt.

Kennt jemand einen Weg dies zu umgehn?
Vielen Dank!!!

Hallo Sandybanks,

ich habe gerade das gleiche Problem. Dieses wird im Thread Transparenz in CustomControl (.NET-Bug?) gerade behandelt.

Grundsätzlich musst Du im OnPaint der PictureBox folgenden Code ergänzen:


SetStyle(ControlStyles.Opaque, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
BackColor = Color.FromArgb(0, 0, 0, 0);

Ich habs zwar in CustomControls eingesetzt, aber ich denke in der PictureBox müsste es auch gehen.

Im o.g. Thread sind auch weiterführende Links zu diesem Thema.

Gruß Ralf

Super! Danke!

Da gibts bei mir aber ein Problem.

Die PicBoxes werden bei mir dynamisch generiert. Wie kann ich deshalb zur Laufzeit die OnPaint-Methode verändern?

Sandybanks: Von der PictureBox ableiten, oder Paint-Event zur Laufzeit hinzufügen.

Ich glaube SetStyle geht nur in der abgeleiteten Klasse!?
Wenn ja, dann ableiten.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

Original von dr4g0n76
Sandybanks: Von der PictureBox ableiten, oder Paint-Event zur Laufzeit hinzufügen.

Ich glaube SetStyle geht nur in der abgeleiteten Klasse!?
Wenn ja, dann ableiten.

Wie meinst das mit dem ableiten? Ich würd dann ja in diesem Fall trotzdem die "Parent"-Klasse bearbeiten wollen.

Also ich hab ein Array von PicBoxes das zur Laufzeit je nach Länge des Arrays erstellt werden. Diese überlappen sich aber zum Teil. Wie kann ich jetzt die oben genannten Zeilen in deren OnPaint-Fkts einfügen?

Ich meinte das so:


   class CPictureBox : PictureBox
    {
        public CPictureBox()
        {
            SetStyle(ControlStyles.Opaque, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            BackColor = Color.FromArgb(0, 0, 0, 0);
        }
    }

Nur in CPictureBox kannst Du die Methoden verwenden. Da diese Protected sind (SetStyle).

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

hm, wenn ich das so mache ist der hintergrund jeder picbox schwarz und teile der inhalte der anderen picboxes liegen im hintergrund.

schaut nicht so gut aus.

Hallo Sandybanks,

den 3-Zeiler, dann ich am Anfang gepostet habe, muss nicht unbedingt im OnPaint-Event liegen, sondern kann auch im Konstruktor sein. Genauer gesagt, er sollte sogar im Konstruktor liegen, da in der OnPaint so wenig wie möglich Code rein sollte (Performance).

Dies wollte ich nur noch anmerken, um Verwirrungen zu vermeiden. Also so wie es dr4g0n76 vorhin gepostet hat!

Wenn Du das Beispiel von dr4g0n76 verwendest hast, hast Du dabei auch beachtet, dass deine Array-Elemente dann auch von Typ CPictureBox sind und nicht PictureBox?

Gruß Ralf

Vielleicht wäre auch das noch wichtig:


   protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x20;
                return cp;
            }
        }

und das:

       protected override void OnPaint(PaintEventArgs e)
        {
            if (m_Image != null)
                e.Graphics.DrawImage(m_Image, (Width / 2) - (m_Image.Width / 2), (Height / 2) - (m_Image.Height / 2));
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        public new Image Image
        {
            get
            {
                return m_Image;
            }
            set
            {
                m_Image = value;
                base.RecreateHandle();
            }
        }

Dann musst Du natürlich noch

Image m_Image deklarieren.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

Eigentlich wollte ich ja hier nicht die ganze Lösung posten, aber probiers mal damit:

in diesem Falle wurde von Panel abgeleitet.


using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace TransPic
{
    class CTransparentPictureBox : Panel
    {
        private Image m_Image = null;

        public CTransparentPictureBox()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.BackColor = Color.Transparent;
            this.Paint += new PaintEventHandler(CTransparentPictureBox_Paint);
            this.BorderStyle = BorderStyle.None;
        }

        void CTransparentPictureBox_Paint(object sender, PaintEventArgs e)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x20;
                return cp;
            }
        }

        protected override void OnMove(EventArgs e)
        {
            base.RecreateHandle();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            //ControlPaint.DrawLockedFrame(e.Graphics, Rectangle.Inflate(this.ClientRectangle, -1, -1), true);
            Color m_clNormal = Color.FromArgb(210, 255, 255, 255);
            e.Graphics.FillRectangle(new SolidBrush(m_clNormal), this.ClientRectangle);
            if (this.m_Image != null)
            {
                e.Graphics.DrawImage(this.m_Image, (Width / 2) - (m_Image.Width / 2), (Height / 2) - (m_Image.Height / 2));
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //has to be empty
        }

        public new Image Image
        {
            get
            {
                return m_Image;
            }
            set
            {
                m_Image = value;
                base.RecreateHandle();
            }
        }
    }
}



EDIT: Habs gerade mal ausprobiert, funktioniert bei mir perfekt. Die Hintergrundfarbe ist durchsichtig. Ein darunterliegender Button würde z.B. durchscheinen.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

danke für eure antworten!

ich werd das alles gleich morgen ausprobieren!!!

Servus zusammen,

ich habe da mal eine Frage wenn ich ca. 20 von diesen Panels (jedes ca. 400x400 px groß) auf ein Form positioniere. Dieses Form minimiere und anschliessend maximiere so Flackert dass ganze.

Bekomme, an welcher Schraube muss ich drehen damit es nicht mehr Flackert?

THX

Hallo MOGNew,

weniger Controls verwenden oder gleich alles selber zeichnen.

Ansonsten das Übliche, was man auch sonst gegen ==> Flackern tun kann.

herbivore

Hallo herbivore,

mir ist aufgefallen, dass das Flackern nur entsteht wenn die Farbe auch Transparent ist. falls dies nicht der Fall ist, so flackert auch nichts......
Kann ich da überhaupt noch was machen....

Doubled Buffer etc steht schon.

Hallo MOGNew,

Kann ich da überhaupt noch was machen....

ich habe ja schon zwei Alternativen genannt.

herbivore

Hrm, alternativ kann man auch Beginn und EndPaint verwenden allerdings nur in verbindung mit der Windows API und überschreiben der WM_PAINT um diese dann wieder auf das OnPaint des Controls zu linken.

Unter dem Artikel: [Artikel] Custom Window Border für Form's](http://www.mycsharp.de/wbb2/thread.php?threadid=27473) habe ich auch noch eine Lösung gegen Flackereffekte geschrieben, diese würde ebenso funktionieren. Sobald CreateParams und somit auch der WindowsStyle sich ändert, kommt es manchmal zu Problem beim Zeichnen.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(