none
Draw from my own Functions to Form ? RRS feed

  • Frage

  • Hi to all,

    how can i draw (Text, Line, Rectangle) from my own written functions or class to a Form, Panel, PictureBox or Form_Paint ?

    best gegards

    ati

    Mittwoch, 28. November 2012 11:22

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

    Donnerstag, 29. November 2012 18:24
    Beantworter

Alle Antworten

  • Hi ati,

    das kannst du machen in dem du die OnPaint Methode überschreibst.

    MFG

    Björn

    Mittwoch, 28. November 2012 11:28
  • 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

    Mittwoch, 28. November 2012 11:39
    Beantworter
  • 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

    Donnerstag, 29. November 2012 08:06
  • 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
    Donnerstag, 29. November 2012 08:34
    Beantworter
  • Hallo, mal zur groben Orientierung: Es gibt 2 Arten um an das Graphics objekt heran zu kommen:

    1. Paint abfangen und Graphics aus den EventArgs hohlen
    2. 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/

    Donnerstag, 29. November 2012 13:55
    Moderator
  • Hallo,

    danke.

    1. ich meine ganz einfach, daß ich im Form1_Paint einen Rahmen auf dem Form zeichne.

    2. aus meiner Funktion im selben Klasse schreibe ich Text und weitere Draws auf dem Form1.

    Wie geht dies ?

    MFG

    Donnerstag, 29. November 2012 15:19
  • Zu 1.:
    Abbonniere Paint und zeichne Mittels

            private 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/

    Donnerstag, 29. November 2012 15:38
    Moderator
  • 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
    Donnerstag, 29. November 2012 17:49
  • 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

    Donnerstag, 29. November 2012 18:24
    Beantworter
  • 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/

    Donnerstag, 29. November 2012 19:18
    Moderator
  • Hallo Herr Elmar,

    danke.

    Das ist die Lösung MeineFkt(e.Graphics);

    MFG

    Samstag, 1. Dezember 2012 13:06
  • 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/

    Samstag, 1. Dezember 2012 13:15
    Moderator
  • Hallo,

    aber eins könnt ihr mir noch verraten:

    wie ich im Clientbereich eines Formulars Rahmen zeichnen kann, wo oben, unten und links welche anderen Steuerelemente positioniert sind ?

    MFG

    Dienstag, 4. Dezember 2012 14:25
  • 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/

    Dienstag, 4. Dezember 2012 14:36
    Moderator
  • Hallo,

    einfacher gesagt: Clientbereich des Forms zu ermitteln.

    MFG

    Dienstag, 4. Dezember 2012 15:02
  • Also der Client-Bereich ist der Bereich in dem du alles selbst bestimmen must. Also der Bereich innerhalb des Rahmens. Die Größe liefert die Size-Eigenschaft der Form.

    Koopakiller [kuːpakɪllɐ] - http://koopakiller.ko.ohost.de/

    Dienstag, 4. Dezember 2012 15:10
    Moderator
  • 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

    Dienstag, 4. Dezember 2012 16:08
    Beantworter