Laden...

Rechteck farbig per Mouseclick

Erstellt von Carreck vor 9 Jahren Letzter Beitrag vor 9 Jahren 2.713 Views
C
Carreck Themenstarter:in
5 Beiträge seit 2015
vor 9 Jahren
Rechteck farbig per Mouseclick

Hallo,

Bin momentan dabei, für die Arbeit eine Übersicht des Lagers zu entwerfen und habe die grobe Struktur fertig. Jetzt möchte ich aber die Farbe einzelner Rechtecke ändern, sobald ich mit der Maus draufklicke. Momentan habe ich folgenden Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
        }

        private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            Graphics grfx = e.Graphics;
            grfx.Clear(System.Drawing.SystemColors.Control);
            System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Blue);
            for (int x = 0; x< 950; x = x+10)
            {
                for (int y = 0; y < 160; y = y+10)
                {
                    Pen pen = new Pen(Color.Blue);
                    grfx.FillRectangle(brush, new Rectangle(x, y, 5, 5));
                }
            }
        }

        private void Form1_MouseClick(object sender, MouseEventArgs f, System.Windows.Forms.PaintEventArgs e)
        {
            int x = Control.MousePosition.X;
            int y = Control.MousePosition.Y;


            Graphics grfx = e.Graphics;
            System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
            grfx.FillRectangle(brush, Rectangle(x, y, 5, 5));
        }

        private Rectangle Rectangle(int x, int y, int p1, int p2)
        {
            throw new NotImplementedException();
        }

    }
}

Wirft soweit keine Fehler aus, aber passieren tut auch nichts. Es bleibt alles so, wie es ist.

Ich denke, ihr könnt mir helfen!
Danke!

Etiam Si Omnes, Ego Non!

2.207 Beiträge seit 2011
vor 9 Jahren

Hallo Carreck,

Ist es Absicht, dass du Variablen definierst, die du nicht verwendest?

hast du mal den Debugger genommen [Artikel] Debugger: Wie verwende ich den von Visual Studio? und geschaut, ob du überhaupt in deine Events reinspringst?

Gruss

Coffeebean

C
Carreck Themenstarter:in
5 Beiträge seit 2015
vor 9 Jahren

Hallo Coffeeban,

Meinst du die Methode ganz unten? Oder das "MouseEventsArg f" in der Methode "Form1_MouseClick"? Die Methode ganz unten habe ich von VS selbst erstellen lassen über Rechtsklick auf Rectangle -> Generieren -> Methodenstub.
Das "MouseEventsArg f" muss drinbleiben, damit MouseClick funktioniert, "System.Windows.Forms.PaintEventArgs e" damit Graphics geht.

Wenn ich die selbstgenerierte Methode unten rausnehme, dann erhalte ich folgenden Fehler:> Fehlermeldung:

Fehler 1 "System.Drawing.Rectangle" ist ein(e) "Typ", wird aber wie ein(e) "Variable" verwendet. C:\Users\XXX\Documents\Visual Studio 2013\Projects\lagerplan_koordinaten\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs 44 39 WindowsFormsApplication1

Und du hast Recht, er spring nicht in das Event rein. Die for-Schleife zur Erzeugung funktioniert aber!

Gruß
Carreck

Etiam Si Omnes, Ego Non!

S
145 Beiträge seit 2013
vor 9 Jahren
private void Form1_MouseClick(object sender, MouseEventArgs f, System.Windows.Forms.PaintEventArgs e)

Ist keine standard methode von .Net die für Ereignisse aufrufe hergenommen wird/werden kann.

Du musst dir den Mausbereich im MouseCklick merken.
Invalidate aufrufen, damit das Formular weiß das es sich neu zeichnen soll.
Und im Paint Ereignis mit den germerkten Bereichen zeichnen.

C
Carreck Themenstarter:in
5 Beiträge seit 2015
vor 9 Jahren

Mit folgendem Code springt er zumindest in das Click-Event..

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
            this.Invalidate();
        }

        private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            Graphics grfx = e.Graphics;
            grfx.Clear(System.Drawing.SystemColors.Control);
            System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Blue);
            for (int x = 0; x< 950; x = x+10)
            {
                for (int y = 0; y < 260; y = y+10)
                {
                    Pen pen = new Pen(Color.Blue);
                    grfx.FillRectangle(brush, new Rectangle(x, y, 5, 5));
                }
            }

        }

        private void Form1_Click(object sender, EventArgs e)
        {
            int pos_X = Control.MousePosition.X;
            int pos_Y = Control.MousePosition.Y;

            Console.Write(pos_X);
        }
    }
}

@Spyke: Mausbereich im Sinne von X-Y-Koordinaten? Per "Control.MousePosition.X bzw. .Y"?
Wo genau muss ich dann das Invalidate aufrufen? (Habs jetzt zum merken erstmal oben in der public Form mit reingeschrieben.
Bzgl. des Pain-Ereignisses: ist es nicht sinnvoller, ein neues Paint-Ereignis dann zu erstellen? Welches nur die erforderlichen Quadrate neu zeichnet?

Gruß
Carreck

Etiam Si Omnes, Ego Non!

L
3 Beiträge seit 2015
vor 9 Jahren

Noup, Paint() zeichnet alles neu.

Du weißt nie, wann genau Paint() ausgeführt wird. Daher musst Du garantieren, dass es immer funktioniert, also alle zum Zeichnen nötigen Daten zugreifbar vorhalten.

Wenn Du nur einen Bereich neu zeichnen willst, nimm eine Überladung von Invalidate()

Invalidate() informiert das Betriebssystem darüber, dass Du ein Control oder einen Bereich desselben neu gezeichnet haben willst. Das BS wird dann irgendwann Paint() aufrufen.

Und zu wann: Für den Anfang immer bei Änderungen, die zu sehen sein sollen. Falls Du etwas verschiebst also bei MouseMove. Wenn etwas blinken soll, dann im Timer.Tick event handler. Bei Asynchronen aufrufen in BackgroundWorker.RunWorkerCompleted.

C
Carreck Themenstarter:in
5 Beiträge seit 2015
vor 9 Jahren

Am ehesten natürlich sofort, nachdem ich geklickt habe. Ich habe also folgendes direkt mal in das Click-Event gepackt:

        private void Form1_Click(object sender, EventArgs e)
        {
            this.Invalidate(new Rectangle(900, 200, 40, 40));
            this.Update();
        }
    }
}

Das bringt aber auch nichts. Aller Anfang ist schwer...

Etiam Si Omnes, Ego Non!

S
145 Beiträge seit 2013
vor 9 Jahren

Springt der Debugger den in das Click Ereignis wenn du dort einen Breakpoint setzt?
Hat dein Formular Steuerelemente?
Denn dann werten diese das Click Ereignis aus und dein Formular bekommt erstmal nixs mit davon.

C
Carreck Themenstarter:in
5 Beiträge seit 2015
vor 9 Jahren

Ja, der Debugger springt in die Methode rein.
Sorry, aber Steuerelemente? 😕
Sobald er bei "this.Update()" angekommen ist, fängt er wieder an, Form1_Paint abzuarbeiten..

Etiam Si Omnes, Ego Non!