Unabhängig von einem Paint-Event zeichnen



  • Hallo,

    Was ich versuche zu machen ist folgendes:

    Ich erstelle eine eigene Klasse Kreis, der Konstruktor enthält Radius und x, sowie y Position des zu zeichnenden Kreises.Eine Draw() Methode zeichnet dann diesen Kreis auf eine PictureBox oder Panel, etc. Soweit wie ich bin funktioniert eigentlich auch alles ganz gut allerdings nicht optimal:
    Um zeichnen zu können benötige ich natürlich ein Graphics Objekt, ich hab dieses dann entweder als Parameter für den Konstruktor, was darin resultierte, dass ich objekte nur innerhalb des PaintEvents instanzieren konnte , was sehr kontraproduktiv ist oder als Übergabeparameter der Draw()-Methode, sodass immer im PaintEvent gezeichnet wurde, was die Instanzierung ausserhalb ermöglicht.

    Das schönste wäre es jetzt allerdings für mich, ein Graphics Objekt als Konstruktorübergabparameter ausserhalb des Paint-Events, jedoch mit den Informationen des Objektes, welches dieses Event auslöste, zu haben, sodass ich Instanzen ausserhalb diesem instanzieren kann UND auch von irgendwelchen Orten aus benutzen kann, v.a. die Draw-Methode.

    Vermutung:
    Ich geh mal stark davon aus, dass ich irgendwelche Methoden überschreiben muss, oder meine Klasse irgendwas erben lassen soll allerdings stellt sich für mich die Frage welche, bzw. was?

    Ich hoffe ihr versteht mich, ich spreche nebenbei von funktionalitäten der
    GDI+ , für den Fall dass das relevant ist.

    Ich hoffe ihr könnt mir helfen!



  • class Circle
    {
      public void Draw(Graphics graphics)
      { 
        // zeichnen
      }
    }
    
    class CircleBox : PictureBox
    {
      public List<Circle> Circles { get; set; }
    
      protected override OnPaint(PaintEventArgs pe)
      {
        foreach(Circle circle in Circles)
          circle.Draw(pe.Graphics);
      }
    }
    

    Jetzt kannst du von außerhalb auf die Liste der Kreise zugreifen und damit anstellen was du willst.



  • Vielen Dank, is ne gute Idee, auch wenns bisher noch nicht funktioniert.

    Es fehlt noch der Rückgabetyp der überschriebenen OnPaint Methode, ich nehme mal void an, wo wir gerade davon sprechen, wann wird diese eigentlich aufgerufen?



  • Den Rückgabetyp findest du in der MSDN dokumentiert, einfach mal F1 drücken und System.Windows.Graphics.UserControl (oder .PictureBox oder...) eingeben und dann OnPaint raussuchen 😉
    Oder den Cursor im Code auf "PictureBox" stellen und dann F1 drücken und hoffen dass es funktioniert (was es meistens tut).

    Und die wird aufgerufen wenn das Framework denkt dass ein Teil des Controls neu gezeichnet werden muss. D.h. wenn z.B. ein Teil eines Fensters sichtbar wird, und Windows die Grafik die da sichtbar sein sollte nicht noch irgendwo gepuffert hat. Also z.B. wenn ein Fenster X vor einem Fenster Y liegt wo ein Control Z drinnen ist, und du verschiebst dann Fenster X so dass ein ehemals verdeckter Teil von Control Z sichtbar wird, dann wird Z.OnPaint aufgerufen.

    Du kannst dem Framework aber natürlich auch mitteilen dass die "gewünschte Grafik" eines Controls sich geändert hat, z.B. weil irgendwelche Daten die das Control anzeigen soll geändert wurden. Das machst du indem du die Funktion Invalidate auf das entsprechende Control (oder auch die ganze Form) aufrufst. Oder anders gesagt: wenn das was OnPaint in der Vergangenheit gezeicht hat nichtmehr "passt" (nichtmehr "gültig" ist, daher auch der Name "Invalidate") rufst du Invalidate() auf.



  • fischlefisch schrieb:

    Es fehlt noch der Rückgabetyp der überschriebenen OnPaint Methode, ich nehme mal void an ...

    richtig

    fischlefisch schrieb:

    wo wir gerade davon sprechen, wann wird diese eigentlich aufgerufen?

    Falls du darauf anspielen willst wie du selbst ein Neuzeichnen veranlassen kannst: Control.Invalidate()

    Ansonsten wird OnPaint


Anmelden zum Antworten