Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Transparente Pictureboxes
Sandybanks
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

Transparente Pictureboxes

beantworten | zitieren | melden

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!!!
private Nachricht | Beiträge des Benutzers
mustang-1969
myCSharp.de - Member



Dabei seit:
Beiträge: 27
Herkunft: Österreich / Nähe Graz

beantworten | zitieren | melden

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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von mustang-1969 am .
private Nachricht | Beiträge des Benutzers
Sandybanks
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

beantworten | zitieren | melden

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?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Sandybanks am .
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 2.921
Herkunft: Deutschland

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Sandybanks
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

beantworten | zitieren | melden

Zitat
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?
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 2.921
Herkunft: Deutschland

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Sandybanks
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
mustang-1969
myCSharp.de - Member



Dabei seit:
Beiträge: 27
Herkunft: Österreich / Nähe Graz

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 2.921
Herkunft: Deutschland

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 2.921
Herkunft: Deutschland

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
Sandybanks
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

beantworten | zitieren | melden

danke für eure antworten!

ich werd das alles gleich morgen ausprobieren!!!
private Nachricht | Beiträge des Benutzers
MOGNew
myCSharp.de - Member



Dabei seit:
Beiträge: 47

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo MOGNew,

weniger Controls verwenden oder gleich alles selber zeichnen.

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

herbivore
private Nachricht | Beiträge des Benutzers
MOGNew
myCSharp.de - Member



Dabei seit:
Beiträge: 47

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo MOGNew,
Zitat
Kann ich da überhaupt noch was machen....
ich habe ja schon zwei Alternativen genannt.

herbivore
private Nachricht | Beiträge des Benutzers
Andreas.May
myCSharp.de - Member

Avatar #avatar-2474.gif


Dabei seit:
Beiträge: 915

beantworten | zitieren | melden

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 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.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Andreas.May am .
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
private Nachricht | Beiträge des Benutzers