Benutzer mit den meisten Antworten
Draw from my own Functions to Form ?

Frage
Antworten
-
Hallo Ati,
CreateGraphics ist für das Zeichnen auf Steuerelementen nicht wirklich geeignet. Denn Windows löst das Paint-Ereignis immer dann aus, wenn es das Fenster oder Teile davon neu zeichnen muss (will).
Verwenden würde man die Methode nur für das Zeichnen auf Bitmaps.
Desweiteren ist das hier auch nicht sinnvoll.
Wenn Du eine Funktion im Paint-Ereignis aufrufst, so verwende die dabei übergebene Graphics Instanz.
private void MeineFkt(Graphics g) { g.DrawString("Hello World", new Font("Arial", 12), Brushes.Black, new PointF(200, 200)); } // und dann in Paint verwenden als: MeineFkt(e.Graphics);
Damit wird die Funktion allgemein verwendbar für unterschiedliche Fenster (Formulare und mehr).
Und ich hatte oben schon mal auf die ControlPaint-Klasse hingewiesen, die ähnlich aufgebaut ist: Der Großteil der Methoden erwartet einen Graphics-Kontext und zeichnet darauf.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 6. Dezember 2012 15:24
Alle Antworten
-
Hallo Ati,
da Du bereits eine Diskussion zum gleichen Thema hattest:
Was hast Du dort nicht verstanden?
In Grafik und Zeichnen in Windows Forms findest Du eine Anleitung zu den Basisaufgaben.
Die Übergabe von Parametern an eigene Methoden wiederum gehört zu den Grundlagen des Klassen-Entwurfs, ist also nicht spezifisch für Zeichenroutinen. Beim Entwurf allgemeiner Zeichenroutinen kann man sich z. B. an die ControlPaint-Klasse anlehnen, die einen Satz von allgemeinen Methoden in Form von statischen Methoden bereitstellt.
Gruß Elmar
-
Hallo,
ja weil da ging es erst um auf Form zu zeichnen.
Hier gehts darum wie man vom eigenen Funktionen auf dem Form zeichnen kann ?
Dies ist mir nicht klar geworden.
Für Bsple wäre ich dankbar.
Wie ist kann ich OnPaint mit irgend eine andere Draw überschreiben ?
MFG
-
Hallo Ati,
Deine Fragen sind leider nicht ganz verständlich.
Ob man auf ein Formular oder ein anderes Steuerelement (Panel, PictureBox uam.) zeichnet spielt keine Rolle. Alle Windows Forms Steuerelemente sind von Control abgeleitet und es handelt sich dabei aus Sicht von Windows um (Kind-)Fenster.
Die Zeichenereignisse (OnPaint, OnPaintBackground) stellen Dir einen Graphics-Kontext zur Verfügung mit dem Du die Zeichenoperationen - sei es Punkte, Linien, Grafiken oder Text uam. - ausführst.
Beispiele hat man Dir bereits in der anderen Diskussion gezeigt. Ohne zu wissen, was Du überhaupt erreichen willst, wirst Du vermutlich wenig damit anfangen können. Eine lose Sammlung wäre http://www.java2s.com/Code/CSharp/2D-Graphics/Catalog2D-Graphics.htm
Gruß Elmar
-
Hallo, mal zur groben Orientierung: Es gibt 2 Arten um an das Graphics objekt heran zu kommen:
- Paint abfangen und Graphics aus den EventArgs hohlen
- CreateGraphics von einem Control aufrufen
Wenn du aus einer Form heraus etws zeichnen willst, kannst entweder CreateGraphics aufrufen und dein Graphics-Objekt erstellen, oder du übergibst Ihr bereits ein Graphics Objekt:
private void Draw() { Graphics g = this.CreateGraphics(); g.DrawRectangle(Pens.Black, 10, 10, 50, 50); } private void Draw(Graphics g) { g.DrawRectangle(Pens.Black, 10, 10, 50, 50); } private void Form1_Paint(object sender, PaintEventArgs e) { Draw(e.Graphics); //Möglichkeit 1, in diesem Fall besser geeignet, da du bereits im besitzt eines Graphics bist } private void button1_Click(object sender, EventArgs e) { Draw();//Möglichkeit 2, in diesem Fall, die einzige Variante }
Ich hoffe es hilft dir, die Theorie hat Elmar dir wohl ausführlichst dargelegt.
Koopakiller [kuːpakɪllɐ] - http://koopakiller.ko.ohost.de/
-
Zu 1.:
Abbonniere Paint und zeichne Mittelsprivate void Form1_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawRectangle(Pens.Black, 10, 10, 50, 50); }
einen Rahmen.
Zu 2.:
In deinem Event-Handler erstellst du ein neues Graphics-Objekt mittels CreateGraphics, auf das du dann deinen Text malst:private void button1_Click(object sender, EventArgs e) { Graphics g = this.CreateGraphics();
g.DrawString("Hello World", new Font("Arial", 12), Brushes.Black, new PointF(20, 20)); }und schon sollte das ganze funktionieren ;)
Ohne dich jetzt verwirren zu wollen, du kannst auch aus deinem Eventhandler Invalidate() aufrufen, dann wird Paint erneut ausgeführt, da musst du aber alles neu Zeichnen, aber das nur so am Rande.
Koopakiller [kuːpakɪllɐ] - http://koopakiller.ko.ohost.de/
-
Hallo,
so sieht mein Code aus:
private void frmMain_Paint(object sender, PaintEventArgs e)
{if (Mouse...)
{
rect = new Rectangle(1, 70, this.ClientRectangle.Right - 2, this.Height - 120);
e.Graphics.FillRectangle(new SolidBrush(Color.White), rect);
e.Graphics.DrawRectangle(p, rect);
MeineFkt();
}
else
{
e.Graphics.ScaleTransform(2, 2);
e.Graphics.DrawString("Hello World!", new Font(new FontFamily("arial"), 20), Brushes.Black, 10 - mouseDown.X + this.Width / 4, 10 - mouseDown.Y + this.Height / 4);
e.Graphics.DrawRectangle(p, new Rectangle(10 - mouseDown.X + this.Width / 4, 10 - mouseDown.Y + this.Height / 4, this.Width - 50, this.Height - 60));
}
}private void MeineFkt()
{
Graphics g = this.CreateGraphics();
g.DrawString("Hello World", new Font("Arial", 12), Brushes.Black, new PointF(200, 200));
}der Text "Hello World" aus der Fkt MeineFkt(); wird dann sofort überdeckt Warum ?
MFG
- Bearbeitet ati.sah Freitag, 30. November 2012 06:58
-
Hallo Ati,
CreateGraphics ist für das Zeichnen auf Steuerelementen nicht wirklich geeignet. Denn Windows löst das Paint-Ereignis immer dann aus, wenn es das Fenster oder Teile davon neu zeichnen muss (will).
Verwenden würde man die Methode nur für das Zeichnen auf Bitmaps.
Desweiteren ist das hier auch nicht sinnvoll.
Wenn Du eine Funktion im Paint-Ereignis aufrufst, so verwende die dabei übergebene Graphics Instanz.
private void MeineFkt(Graphics g) { g.DrawString("Hello World", new Font("Arial", 12), Brushes.Black, new PointF(200, 200)); } // und dann in Paint verwenden als: MeineFkt(e.Graphics);
Damit wird die Funktion allgemein verwendbar für unterschiedliche Fenster (Formulare und mehr).
Und ich hatte oben schon mal auf die ControlPaint-Klasse hingewiesen, die ähnlich aufgebaut ist: Der Großteil der Methoden erwartet einen Graphics-Kontext und zeichnet darauf.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 6. Dezember 2012 15:24
-
Abgesehen, das in deinem Code ein if fehlt, kann es viele Gründe haben.
Da du dein Graphics Objekt ja neu erzeugst und nicht in Paint zeichnest, hast du das Problem, das bei einer Aktualisierung des Fensters, deine Schrift wieder verschwindet, siehe Invalidate(). Wenn das aufgerufen wird, dann wird wie gesagt Paint neu ausgeführt und es wird neu gezeichnet. Dazu musst du deinen Text natürlich in Paint packen. Um den TextWieder zu löschen, reicht es schon das Fenster mal kurz unter die Taskleiste zu schieben und wieder hoch zu ziehen, danach ist der Text wieder weg.
Eine weitere Möglichkeit könnte sein das du bereits Invalidate wo anders aufrufst, was zur Folge hat, das alles aktualisiert wird, also das selbe Verhalten zeigt, wie wenn man das Fenster aus dem Bildschirm schiebt.
Genausogut könnte dein Text aber auch ganz einfach übermalt werden.
Koopakiller [kuːpakɪllɐ] - http://koopakiller.ko.ohost.de/
-
Wenn du den Code aus meinem ersten Post gelesen hättest, hättest du auch die Variante gehabt:
private void Draw(Graphics g) { g.DrawRectangle(Pens.Black, 10, 10, 50, 50); } private void Form1_Paint(object sender, PaintEventArgs e) { Draw(e.Graphics); //Möglichkeit 1, in diesem Fall besser geeignet, da du bereits im besitzt eines Graphics bist }
Das CreateGraphics nicht die erste Wahl ist, erläuterte ich bereits in deinem anderen Thread.Koopakiller [kuːpakɪllɐ] - http://koopakiller.ko.ohost.de/
-
Hallo, einen Rahmen kannst du mit e.Graphics.DrawRectangle() malen. Dabei musst du natürlich wissen wo deine anderen Controls so sind. Die Größe der Form ist in der Eigenschaft Size gespeichert. Damit kannst du dann entsprechend die Größen deiner Rahmen berechnen.
Koopakiller [kuːpakɪllɐ] - http://koopakiller.ko.ohost.de/
-
-
Hallo zusammen,
kleine Korrektur:
Der Client-Bereich ohne Rahmen, Bildlaufleisten und Titelleiste wird durch ClientSize definiert bzw. durch ClientRectangle - wobei links oben hier 0, 0 ist.Wobei es noch ein DisplayRectangle gibt, das von erweiterten Steuerelementen überschrieben werden kann, um den Arbeitsbereich des Steuerelements zu definieren - Vorgabe ist hier ClientRectangle.
ScrollableControls ziehen dort z. B. das Padding ab.Gruß Elmar