2016-07-24 15 views
0

Ich habe festgestellt, dass es einen Unterschied zwischen Grafik g und e.Graphics von Paint-Ereignis gibt .. e.Graphics ist so etwas wie "mehr PRO", die mehr Spaß mit Transformationen Matrizen ermöglicht.
Transformationen wie diese https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspxe.Graphics Verwendung

Ich schreibe App, wo mehrere Objekte sein werden. In dieser Frage gibt es beispielsweise C# rotation (transformation) issue

fand ich, wie OnPaint-Methode hier overrided werden konnte https://msdn.microsoft.com/en-us/library/b818z6z6(v=vs.71).aspx


Das glaube ich nicht verstehe, ist usecase, wie ich es verwenden soll. Ich muss OnPaint-Methode überschreiben - ok, aber auf welches Objekt ??

Ermöglicht einfache Situation vorstellen, ich Formular in C# haben

public partial class Form1 : Form { 

private Bitmap canvasBitmap; //bitmap for drawing 
private Graphics g;   
... 

public Form1() { 
     //on Form there is placed PictureBox called canvas 
     //so canvas is PictureBox 640x480 px 
     canvasBitmap = new Bitmap(canvas.Width, canvas.Height); 
     canvas.Image = canvasBitmap; 

     //prepare graphics 
     g = Graphics.FromImage(canvasBitmap); 
     g.SmoothingMode = SmoothingMode.AntiAlias; 
     ... 
     g.Invalidate();  
} 
} 

wird Alle Zeichnung auf PictureBox geschehen, die meine Leinwand sein wird. Ist es okay, dort die Graphics g zu halten und nicht die e.Graphics?

als ich einige Objekte haben:

List<Fish> fishes = new List<Fish>(); 
List<Food> food = new List<Food>(); 

Und ich will mit ihnen etwas Spaß Sachen zu tun, wollen zum Beispiel einige Transformationen wie hier (Scaling, Translation, Rotation) https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspx

Hier sind die Objekte. Ich habe versucht, dass die OnPaint-Methode zu schreiben (nicht sicher, ob sein auf richtige Stelle.)

class Fish { 
    Point position; 

     Fish(int x, int y) { 
     ... 
     } 

    protected override void OnPaint(PaintEventArgs e){ 
    ... 
    } 
} 


    class Food { 

     Point position; 

     public Food(int x, int y) { 

     ... 
    } 

    protected override void OnPaint(PaintEventArgs pe) { 

     .... 
    } 

} 

Die Frage ist: Wie soll in diesem Fall OnPaint-Methode verwendet werden? Was ist der Verwendungszweck? Ich schätze, ich werde diese Methode bei Fish and Food wahrscheinlich außer Kraft setzen, so wie ich es getan habe. Wie zeichne ich es? Wie ich es neu zeichne? Wie lege ich es auf meine Grafik g Leinwand in Form? Wo und wie sollte verwendet werden Invalidate?
normaly verwenden i

canvas.Invalidate(); 

das Formular Beispiel. Kann ich Graphics g und e.Graphics mischen? Es könnte auch bei e.Graphics etwas Doppelpufferung oder ähnliches geben.

bearbeiten
E1) So Formular und PicutreBox sind Kontrolle? Meine Fisch- und Lebensmittelklasse wird nicht kontrolliert? OK?
E2) Auf Picture Box kann irgendwie bis zu 3 Grafiken kann ich wechseln und es ist für glatte Zeichnung. Aber der Einfachheit halber kann ich bei einem bleiben? OK?
E3) Grafik g ist Tool e.Graphics ist ein Wrapper einiger Grafikbibliotheken, die einige Unterstützung für Transformatinen haben (arbeiten mit Transformationsmatrizen). OK?
E4)OnPaint(PaintEventArgs e) wird mich in die Lage versetzen, e.Grafiken, aber wenn ich meine "Schleife" im Timer habe (im Griff des Timer-Objekts, das ich einfach auf mein Formular setze und den Punkt festlege) und von dort rufe ich die Methode zur Aktualisierung auf und aktualisiere alle Objekte von Fischen und Essen in einigen Listen (Update = mache mit ihnen Transformationen nach meiner Berechnung). Ist es irgendwie möglich die Methoden von e.Graphics hier zu verwenden?
E5) Wenn E1 wahr ist, ist die Override OnPaint-Methode in Essen und Fisch-Klasse Unsinn ok?

+2

Die Verwendung von Graphics.FromImage() ist hier okay, Sie zeichnen auf die Bitmap, nicht auf den Bildschirm. Es ist PictureBox.OnPaint(), das malt. Sie müssen Hilfe leisten und die PictureBox.Invalidate() -Methode aufrufen, um sie darüber zu informieren, dass Sie die Bitmap geändert haben und daher neu gezeichnet werden müssen. Größtes Problem ist mit der Bildgröße, Leinwand. Breite/Höhe ist die * Design * Größe, es wird nicht die tatsächliche Größe auf jedem modernen Computer sein. Oder wenn der Benutzer die Größe des Fensters ändert. Verwenden Sie das Ereignis PictureBox.Resize, um zu wissen, dass das Bild angepasst werden muss. –

+0

Nun das Formular ist Kontrolle, PictureBox ist Kontrolle, meine Fisch-Klasse oder Food-Klasse ist nicht kontrolliert? Meine Motivation in diesem Moment ist Einfachheit und Arbeitskram. Ich muss nur mit über 60 Objekten arbeiten, ihr Verhalten mit dem neuronalen Netz zählen und sie einfach zeigen. Wenn ich OnePaint-Methode verwenden werde, kann ich e.Graphics bekommen, aber wie kann ich das e.Graphics zum Beispiel im Timer verwenden (Timer-Handle-Methode, die auf meinem Formular ist)? Die graphisc g-Methoden sind einfach aufzurufen, aber ich habe nicht gelernt, wie man e.Graphics-Methoden explizit verwendet. Einziger Vorteil von e.Graphics ist für mich, dass es mehr Methoden für Transformationen hat. – user1097772

+1

E1: Ys und nein. E2: PBox kann Image, BackgoundImage und seine Oberfläche haben. Ja, Sie können mit nur einem bleiben. E3: Grafik ist die gleiche Klasse, egal woher du kommst. Nein. In der Timer.Tick Sie nur __ triggerr__ die Farbe durch Aufruf Invalidate auf dem Steuerelement. Die Farbe muss dann Zugriff auf die Daten haben, am besten durch Speichern der Daten (Koordinaten usw.) in einer oder mehreren oder einer Liste von Klassenstufen. E5: In der Tat, es gibt keine Basis (jenseits des Objekts) und daher nichts zu übersteuern. – TaW

Antwort

1

e.Graphics kommt aus dem OnPaint oder Paint Ereignis und daher nur für Kontrollen.

Das Graphics Objekt Sie aus einer Bitmap erstellen ist nur für dieses Bitmap.

Sie sollten die verwenden, die Sie eigentlich wollen: Zeichnen Sie auf der Oberfläche oder in eine Bitmap.

Beachten Sie, dass die Bitmap in einer Steuerung möglicherweise (unter der Oberfläche) angezeigt wird oder nicht.

A picturebox zum Beispiel selbst kann zwei Bitmaps unter seiner Oberfläche angezeigt werden, so dass man für sie dreiGraphics Objekte verwenden möchten ..

Sie tun, um die gleichen Dinge verschiedenen Pixel und nein, du kann nicht mehr mit einem .. tun! Sie können Matrix- und andere Umwandlungen mit beiden Methoden anwenden.

Der Grund, warum die e.Graphics Parameter von OnPaint sind, ist, dass das System einige seiner Bedienelemente in einer Form einige Male neu streichen muss und daher Ihren Zeichnungscode zusätzlich zu den internen Steuerzeichenroutinen aufrufen muss.

Sie müssen also dieses Ereignis und/oder seine e.Graphics verwenden, sonst wird Ihre Zeichnung bei einem solchen Neuzeichnen verschwinden. Wenn Sie e.Graphics zum Zeichnen auf Steuerelemente verwenden, wird die Zeichnung persistent. (*)

Die Bitmaps auf der anderen Seite werden immer in ihrem aktuellen Zustand angezeigt. Keine Notwendigkeit, sie neu zu zeichnen; Rufen Sie einfach Refresh() an, nachdem Sie Ihre Änderungen abgeschlossen haben, um das System über sie zu informieren.

Schließlich: DoubleBuffering ist eine Eigenschaft für Steuerelemente, nicht das Objekt Graphics. Beachten Sie, dass dies für die meisten, insbesondere Container wie Panel, ausgeblendet ist. Um sie einzuschalten, müssen Sie sie daher untergliedern. PictureBox ist zum Zeichnen gedacht und hat DoubleBuffered = true out of the box.

Das Graphics Objekt enthält keine enthalten keine Grafiken; Es ist ein Werkzeug, mit dem Sie auf eine verwandte Bitmap zeichnen können, einschließlich der Oberfläche eines Steuerelements.

(*) Beachten Sie, dass nicht alle Zeichnung Bedürfnisse oder soll bestehen bleiben: Ein rubber Linie oder Rechteck sollte nicht und hier gibt es die 3. Graphics construstor verwenden: Graphics g = someControl.CreateGraphics();.

+0

Wow, aber bitte sehen Sie meine Edit – user1097772