Archief - [ALG]C# Cirkel of Kruis bij klikken

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Shotterke

Legacy Member
Ik ben bezig met een scoutingprogramma te maken. Ik heb alles al gemaakt buiten een van de belangrijkste onderdelen. :p

Elke speler heeft een afbeelding van de helft van een basketbal veld.
Als een speler van een bepaalde positie schiet en scoort, moet je klikken met je linkermuisknop op de juiste plaats van de afbeelding en dan moet er een cirkel verschijnen.
Als hij mist moet er een kruis verschijnen op de plaats waar je met je rechtermuisknop klikt. :s

Nu heb ik geen enkel idee hoe ik dit zou moeten doen.
Ik heb al op verschillende sites gezocht maar ik vind niets dat mij kan helpen.
Hopelijk kan iemand van die forum het. :)

Krueger

Legacy Member
Een mogelijkheid lijkt mij:

Je houdt 2 lijsten bij met punten, een voor de cirkels, en een voor de kruisjes. Die lijsten bevatten dus x,y coordinaten.

Je vangt de Onclick event op, door de argumenten van deze event kan je weten of er met de linkermuis of met de rechtermuis is geklikt. Voeg nu in de juiste lijst de nieuwe x,y coordinaten toe van de muis.

Override de OnPaint event. Overloop uw lijsten, voor de ene lijst teken je cirkels (e.Graphics.DrawEllipse) , en voor de andere lijst teken je een kruis ( 2* e.Graphics.DrawLine)

Dat zou het hem zo moeten doen.

Albireo

Legacy Member
Ik zou zoiets doen:

Code:
        protected override void OnMouseClick(MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                this.positions.Add(new ShootPosition(e.Location,true));
                using (Graphics g = Graphics.FromHwnd(this.Handle)) {
                    g.DrawEllipse(Pens.DarkGreen, e.Location.X - 4, e.Location.Y - 4, 9, 9);
                }

            }
            else if (e.Button == MouseButtons.Right) {
                this.positions.Add(new ShootPosition(e.Location,false));
                using (Graphics g = Graphics.FromHwnd(this.Handle)) {
                    g.DrawLine(Pens.DarkRed, e.Location.X - 4, e.Location.Y - 4, e.Location.X + 4, e.Location.Y + 4);
                    g.DrawLine(Pens.DarkRed, e.Location.X + 4, e.Location.Y - 4, e.Location.X - 4, e.Location.Y + 4);
                }
            }
        }

En als de achtergrondtekening van het veld resizeable moet zijn, OnResize opvangen, vandaar een Refresh() aanroepen, OnPaint opvangen en daarin de code zetten die alle kruisjes en cirkeltjes opnieuw tekent rekening houdend met de resize...


Klein vraagje: als je OnMouseClick, OnPaint,... whatever override is het dan noodzakelijk/nuttig/overbodig om base.OnMouseClick(e), base.OnPaint(e) aan te roepen in de method die de override doet?

Shotterke

Legacy Member
Bedankt alletwee.
het enigste probleem dat ik nog heb is dat is de cirkel of het kruisje niet in mijn picturebox krijg en dat als ik een kruisje wil zetten hij een lijn zet van de linker kan van mijn scherm tot de plaats waar ik geklikt heb :s

Albireo

Legacy Member
Dit zal werken:
Code:
protected override void OnPaint(PaintEventArgs e) {
            // dit is de OnPaint van je Form
            using (Graphics g = Graphics.FromHwnd(this.pictureBox.Handle)) {
                foreach (ShootPosition pos in this.positions) {
                    if (pos.Hit) {
                        g.DrawEllipse(Pens.DarkGreen, pos.Position.X - 4, pos.Position.Y - 4, 9, 9);
                    }
                    else {
                        g.DrawLine(Pens.DarkRed, pos.Position.X - 4, pos.Position.Y - 4, pos.Position.X + 4, pos.Position.Y + 4);
                        g.DrawLine(Pens.DarkRed, pos.Position.X + 4, pos.Position.Y - 4, pos.Position.X - 4, pos.Position.Y + 4);
                    }
                }
            }
            base.OnPaint(e);
        }

Als je e.Graphics gebruikt werkt het niet. Ik vermoed dat als je e.Graphics gebruikt je op de Form zelf aan het tekenen bent (de achtergrond). En omdat de PictureBox "voor" de Form staat, zie je de cirkels en kruisjes niet. Om dat te vermijden moet je de graphics van je PictureBox zelf gebruiken.

Die lijn als je een kruisje zet betekent waarschijnlijk dat je ergens een 0 als x-coördinaat gebruikt.

Shotterke

Legacy Member
De cirkels en kruisjes werken nu.
Ik was inderdaad vergeten een 2de coördinaat mee te geven.
Maar het lukt nog altijd niet om het in een picturebox te steken.

Code:
        private void picBPaint1_MouseClick(object sender, MouseEventArgs e)
        {
            Graphics g = Graphics.FromHwnd(this.picBPaint1.Handle);

            // Add to points collection.
            if (e.Button == MouseButtons.Left)
            {
                myPtsC.Add(new Point(e.X, e.Y));
            }
            else if (e.Button == MouseButtons.Right)
            {
                myPtsK.Add(new Point(e.X, e.Y));
            }
            Invalidate();
        }

        private void picBPaint1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            foreach (Point p in myPtsC)
                g.DrawEllipse(new Pen(Color.Green), p.X, p.Y, 10, 10);
            foreach (Point p2 in myPtsK)
            {
                g.DrawLine(new Pen(Color.Green), p2.X - 4, p2.Y - 4, p2.X + 4, p2.Y + 4);
                g.DrawLine(new Pen(Color.Green), p2.X + 4, p2.Y - 4, p2.X - 4, p2.Y + 4);
            }
        }

Dit is mijn code.
picBPaint is de picturebox waar de cirkels in moeten komen.

Edit:

Ik maak geen gebruik van die Protected override omdat ik er nog nooit van gehoord heb en als ik Albireo's code gebruik een foutmelding krijg bij Shootposition en position :p

Albireo

Legacy Member
Zet de code die nu in je picBPaint1_Paint staat in
Code:
protected override void OnPaint(PaintEventArgs e) {}
en gebruik daar
Code:
Graphics g = Graphics.FromHwnd(this.picBPaint1.Handle);
i.p.v e.Graphics. In je MouseClick-event mag je die Graphics-regel wegdoen omdat je die daar niet gebruikt.

edit: Ik had er waarschijnlijk bij moeten zeggen dat ShootPosition m'n eigen uitvinding is.
Code:
    public struct ShootPosition {
        public ShootPosition(Point position, bool hit):this() {
            this.Position = position;
            this.Hit = hit;
        }
        // de plaats vanwaar de bal geworpen wordt
        public Point Position {
            get;
            set;
        }
        // is het al dan niet een -euh- doelpunt
        // wordt de term doelpunt wel in basketbal gebruikt???
        public bool Hit {
            get;
            set;
        }
    }

En van deze struct heb ik een List<ShootPosition> gemaakt. Ik vond 1 List meer voor de hand liggend dan 2 en 't is ook handig als je alle posities wilt opslaan in een XML-document.

Shotterke

Legacy Member
Nu werkt het perfect!!
Bedankt :p

Nog een vraagje. :p
Wanneer moet je protected override void OnPaint(PaintEventArgs e) gebruiken en voor wat moet je dit gebruiken? :s

EDIT: Ik ben begonnen met de code op alle pictureboxes toe te passen (12 per form) maar hoe kan ik ervoor zorgen dat hij die OnPaint op meerde pictureboxes toepast? Want in je code kun je OnPaint maar 1 keer gebruiken :s

Albireo

Legacy Member
Ik heb 6 jaar geleden geleerd dat als je moet tekenen je daarvoor de OnPaint-methode moet gebruiken. Dat ging dan wel over Java. In mijn pas gekochte boek "Pro C# 2008 and the .NET Platform 3.5" gebruiken ze altijd de Paint-methode om te tekenen en zeggen ze dat het via OnPaint eventueel ook kan.

Anyway die OnPaint erf je van Control vandaar het gebruik van "override" en die is gebrandmerkt als "protected" vandaar dat alle erfgenamen ook "protected" moeten gebruiken.

Als je 12 PictureBoxen hebt, heb je alles in twaalfvoud nodig: 12 lists om alle posities bij te houden, voor elke PictureBox het bijhorende MouseClick-event en in je OnPaint voor elke PictureBox het bijhorende Graphics-object en 12 keer de code om alles te tekenen.

Shotterke

Legacy Member
Albireo zei:
Ik heb 6 jaar geleden geleerd dat als je moet tekenen je daarvoor de OnPaint-methode moet gebruiken. Dat ging dan wel over Java. In mijn pas gekochte boek "Pro C# 2008 and the .NET Platform 3.5" gebruiken ze altijd de Paint-methode om te tekenen en zeggen ze dat het via OnPaint eventueel ook kan.

Anyway die OnPaint erf je van Control vandaar het gebruik van "override" en die is gebrandmerkt als "protected" vandaar dat alle erfgenamen ook "protected" moeten gebruiken.

Als je 12 PictureBoxen hebt, heb je alles in twaalfvoud nodig: 12 lists om alle posities bij te houden, voor elke PictureBox het bijhorende MouseClick-event en in je OnPaint voor elke PictureBox het bijhorende Graphics-object en 12 keer de code om alles te tekenen.

Ik had het ondertussen al gevonden :p
Maar toch bedankt :niceone:

killer9

Legacy Member
straatloper zei:
De cirkels en kruisjes werken nu.
Ik was inderdaad vergeten een 2de coördinaat mee te geven.
Maar het lukt nog altijd niet om het in een picturebox te steken.

Code:
        private void picBPaint1_MouseClick(object sender, MouseEventArgs e)
        {
            Graphics g = Graphics.FromHwnd(this.picBPaint1.Handle);

            // Add to points collection.
            if (e.Button == MouseButtons.Left)
            {
                myPtsC.Add(new Point(e.X, e.Y));
            }
            else if (e.Button == MouseButtons.Right)
            {
                myPtsK.Add(new Point(e.X, e.Y));
            }
            Invalidate();
        }

        private void picBPaint1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            foreach (Point p in myPtsC)
                g.DrawEllipse(new Pen(Color.Green), p.X, p.Y, 10, 10);
            foreach (Point p2 in myPtsK)
            {
                g.DrawLine(new Pen(Color.Green), p2.X - 4, p2.Y - 4, p2.X + 4, p2.Y + 4);
                g.DrawLine(new Pen(Color.Green), p2.X + 4, p2.Y - 4, p2.X - 4, p2.Y + 4);
            }
        }

Dit is mijn code.
picBPaint is de picturebox waar de cirkels in moeten komen.

Edit:

Ik maak geen gebruik van die Protected override omdat ik er nog nooit van gehoord heb en als ik Albireo's code gebruik een foutmelding krijg bij Shootposition en position :p


In je code gebruik je myPtsC en myPtsK. Heb je deze eerst nog gedefinieerd?
Als ik deze code probeer uit te voeren herkent hij deze namen niet.

Albireo

Legacy Member
killer9 zei:
In je code gebruik je myPtsC en myPtsK. Heb je deze eerst nog gedefinieerd?
Als ik deze code probeer uit te voeren herkent hij deze namen niet.

LOL, deze thread is al 2,5 jaar oud. :crazy:

Anyway, ik ben de OP niet maar zo te zien zijn dat fields van het het type List<Point>
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan