[C#, GUI] Transparency niet echt transparant

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer in C# met VS2008 een formulier te maken die er ongeveer uitziet als dit voorbeeld:
Afbeeldingslocatie: http://www.iconexperience.com/_img/showcase_settings_editor.png

Allereerst lukt het me niet om de background image van het formulier rechtsonder te krijgen. Het is me wel gelukt door een picturebox te plaatsen met het plaatje.
Klopt het dat je de background image niet kunt positioneren?

Vervolgens heb ik een aantal flat buttons geplaats met een plaatje en tekst. Dat werkt op zich goed.
Maar ondanks dat ik de background color van de button op transparant heb gezet, wordt die eigenlijk gezet op de background color van het form.
Met als gevolg dat als ik mijn form smaller maak en de picturebox onder/achter de button komt, de button niet een deel van het plaatje van de picturebox laat doorschemeren maar dat er een grijs kader over mijn plaatje heen ligt.
Dus als je naar het ingevoegde plaatje kijkt, om Behaviour (tweede optie) zit een grijs kader, die je niet ziet, behalve waar het achtergrondplaatje zit: de bovenkant van de stift wordt gedeeltelijk afgeschermd door het kader.

Ik heb het ook geprobeerd met een picturebox en een label ipv een button, maar hetzelfde resultaat.
Is er nog een instelling die ik over het hoofd heb gezien? Of moet ik een ander control gebruiken?

Graag jullie advies.

Acties:
  • 0 Henk 'm!

  • HawVer
  • Registratie: Februari 2002
  • Laatst online: 03-09 19:59
Klopt het dat je de background image niet kunt positioneren?
Klopt
Vervolgens heb ik een aantal flat buttons geplaats met een plaatje en tekst. Dat werkt op zich goed.
Maar ondanks dat ik de background color van de button op transparant heb gezet, wordt die eigenlijk gezet op de background color van het form.
Nee, transparantie in Windows Forms betekent dat de achtegrond van de parent form wordt gekopieerd tijdens het painten. Dit betekent dus dat de buttons niet echt 'doorzichtig' zijn. Aangezien de picturebox niet de achtergrond is wordt het plaatje niet gekopieerd.

Een oplossing is om een afgeleide form te maken en daar tijdens het painten de afbeelding te plaatsen op het canvas van de form. Dan kun je ook de positie bepaling doen van klembord plaatje.

http://msdn.microsoft.com...g.graphics.drawimage.aspx

Ik weet niet zeker of dit ook goed gaat met de transparantie. Dit zul je moeten testen. :) Ik ben even te lui om dit te testen. O-)

http://hawvie.deviantart.com/


Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 07:32
Je kunt toch gewoon de OnPaint van je formulier overervenriden en zelf even de background tekenen? Is zo gedaan, kun je DrawBitmap doen en de resize tekent hem dan automagisch rechtsonderin.

Over transparantie weet ik niets ;)

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BackgroundImageTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            
            e.Graphics.Clear(this.BackColor);
            Image backgroundImage = MainResources.FormBackgroundImage;
            Point backgroundImageLocation = new Point();
            backgroundImageLocation.X = this.Width - backgroundImage.Width;
            backgroundImageLocation.Y = this.Height - backgroundImage.Height;
            e.Graphics.DrawImage(backgroundImage, backgroundImageLocation);
            base.OnPaint(e);
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this.Invalidate(true);
        }
    }
}


Alleen nog iets met dubbel buffering doen als je het knipperen weg wil werken...
Of alleen border slepen toestaan... Of resize uitzetten ;)

[ Voor 73% gewijzigd door FireDrunk op 14-01-2010 14:57 ]

Even niets...


Acties:
  • 0 Henk 'm!

  • boe2
  • Registratie: November 2002
  • Niet online

boe2

'-')/

De screen die jij post is hoogstwaarschijnlijk een WPF formulier, en daarin is het een eitje om die layout te verkrijgen. The right tools for the right job ;)

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind.' - Pratchett.


Acties:
  • 0 Henk 'm!

Verwijderd

thijs_cramer schreef op donderdag 14 januari 2010 @ 14:28:
Je kunt toch gewoon de OnPaint van je formulier overervenriden en zelf even de background tekenen? Is zo gedaan, kun je DrawBitmap doen en de resize tekent hem dan automagisch rechtsonderin.

Over transparantie weet ik niets ;)

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BackgroundImageTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            
            e.Graphics.Clear(this.BackColor);
            Image backgroundImage = MainResources.FormBackgroundImage;
            Point backgroundImageLocation = new Point();
            backgroundImageLocation.X = this.Width - backgroundImage.Width;
            backgroundImageLocation.Y = this.Height - backgroundImage.Height;
            e.Graphics.DrawImage(backgroundImage, backgroundImageLocation);
            base.OnPaint(e);
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this.Invalidate(true);
        }
    }
}


Alleen nog iets met dubbel buffering doen als je het knipperen weg wil werken...
Of alleen border slepen toestaan... Of resize uitzetten ;)
Close but no cigar. Je moet OnPaintBackground overriden om dat te doen ;)

En je moet de volgende drie dingen niet vergeten:
C#:
1
2
3
4
5
6
7
8
        public Form1()
        {
            InitializeComponent();

            base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            base.SetStyle(ControlStyles.ResizeRedraw, true);
        }


iig beter dan OnSizeChanged() overriden ;)
Boeboe schreef op donderdag 14 januari 2010 @ 15:10:
De screen die jij post is hoogstwaarschijnlijk een WPF formulier, en daarin is het een eitje om die layout te verkrijgen. The right tools for the right job ;)
Hij heeft het over FlatButtons, dat is duidelijk géén WPF ;)

[ Voor 17% gewijzigd door Verwijderd op 14-01-2010 15:22 ]


Acties:
  • 0 Henk 'm!

  • boe2
  • Registratie: November 2002
  • Niet online

boe2

'-')/

Hij heeft het over FlatButtons, dat is duidelijk géén WPF
Waar hij nu in bezig is niet nee. Mijn suggestie is om het eens met WPF te proberen ;)

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind.' - Pratchett.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt allemaal. Ik zal het gedeelte over OnPaintBackground uitproberen. Ziet er inderdaad niet heel moeilijk uit ;)

Zeer waarschijnlijk is de screen shot die ik als voorbeeld heb gebruikt inderdaad gemaakt in WPF. Maar ik ben vooralsnog gebonden aan WinForms en daar moet het toch ook in kunnen?

Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 07:32
Jazeker, ik wil best nog even een stukje pseudocode voor je schrijven hoor ;)

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BackgroundImageTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            
            e.Graphics.Clear(this.BackColor);
            Image backgroundImage = MainResources.FormBackgroundImage;
            Point backgroundImageLocation = new Point();
            backgroundImageLocation.X = this.Width - backgroundImage.Width;
            backgroundImageLocation.Y = this.Height - backgroundImage.Height;
            e.Graphics.DrawImage(backgroundImage, backgroundImageLocation);
            base.OnPaint(e);
        }
    }
}


Et Voila! werkt perfect ;)

* FireDrunk heeft de afgelopen weken teveel C++ geprogrammeerd... 8-)

[ Voor 88% gewijzigd door FireDrunk op 14-01-2010 15:53 ]

Even niets...


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor je code. Ik had al begrepen dat het plaatsen van een achtergrondplaatje via OnPaintBackground zou moeten werken.
Wat ik bedoelde met mijn opmerking "het moet toch ook met WinForms kunnen" is de transparantie van de buttons. Of is dat nu ook opgelost met de voorgestelde OnPaintBackground methode?
Ik kan vandaag even niet bij mijn code, maar zal het morgen gelijk uitproberen.

Acties:
  • 0 Henk 'm!

Verwijderd

Als je van je Flat buttons de BackColor op Transperant zet moet het werken ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Inderdaad zijn de buttons transpararant je een background image gebruikt.
Met de code van thijs_cramer is het me ook gelukt. Ik hou wel geflikker als ik mijn formulier verklein of vergroot, ondanks dat ik DoubleBuffer heb aangezet. Maar dat is niet zo erg.
Bedankt allen!
Pagina: 1