Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

21

20.02.2013, 15:52

Ok, Wpf finde ich ein bisschen zu umständlich in einer WindowsForms Anwendung.

Folgender Quellcode funktioniert zwar, aber nur kurz, dann bleibt komischerweise die Anzeige hängen:

Pen p1 = new Pen(Color.Blue, 1);
panel1.CreateGraphics().DrawEllipse(p1, x, y, 1, 1);

Wenn ich es so mache funktioniert es immer, aber natürlich nur wenn ich die Größe des Formulares per Hand verändere:
private void panel1_Paint(object sender, PaintEventArgs e)
{

Graphics g = e.Graphics;
Pen p1 = new Pen(Color.Blue, 1);
g.DrawEllipse(p1, x, y, 1, 1);
}

Gibt es eine Möglichkeit panel1_Paint manuell aufzurufen?
Was ist der Unterschied zwischen beide Codeschnippseln? Der obere lässt sich in jeder gewünschten Methode platzieren, der untere natürlich nicht. Kann es sein, dass beim oberen Quellcode der Grund darin liegt, dass der Arbeitsspeicher irgendwann "überläuft"?

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

22

21.02.2013, 15:00

Ich weis, Doppelposts sollte man eher vermeiden, aber hat den wirklich niemand eine Idee, oder habe ich meine Frage nur zu schlecht formuliert?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

23

21.02.2013, 19:57

Na ja, Du zeigst nicht gerade viel. Man kann nur raten, WIE Du den ersten Code wohl einsetzt.
Die zweite Methode kann man natürlich auch selbst aufrufen, die Frage ist bei beiden aber wohl eher: Wann?
Wenn Du z.B. mit Timern arbeitest, dann wird Dir der erste Code wohl deswegen scheitern, weil Du Thread-übergreifend in Deinem Fenster herum pfuschst, was die gar nicht gut finden.
Schlussfolgerung also: Mehr Code, mehr Info.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

24

23.02.2013, 11:04

In meiner Simulation kommen alle paar Sekunden neu Objekte hinzu. Am Ende sind es ca. 300 Kreise, dass sollte GDI+ aber doch wohl schaffen... Ich habe 4gb Arbeitsspeicher und einen Intel i5, wobei das Problem wohl eher an meinem Quellcode liegt.


Versuch 1

Nachdem ich ein neues Objekt in meinem Array hinzugefügt habe, rufe ich meine Methode AnsichtNeuZeichnen() auf, welche wiederum für jedes Objekt in einer foreach Schleife diesen Quellcode ausführt (x und y sind natürlich immer unterschiedlich).

Pen p1 = new Pen(Color.Blue, 1);
panel1.CreateGraphics().DrawEllipse(p1, x, y, 1, 1);



Am Anfang klappt das auch gut und ich sehe immer mehr Kreise. Da die Position der existierenden Kreise sich auch mit der Zeit ändert, reicht es natürlich nicht, wenn ich einfach einen neuen Kreis hinzufüge, sondern vorher "leere" ich die Anzeige mit Panel1.Invalidate(). Ab ca. 200 Objekten sehe ich aber komischerweise keine Veränderung in der Anzeige mehr, ob wohl sich die Variablenwerte trotzdem ändern. Zudem flakert das Bild auch sehr, obwohl die Ansicht nur teilweise alle 3 sek. neu gezeichnet wird. Manchmal funktioniert die Simulation so auch länger, manchmal friert die Ansicht früher ein.


Versuch 2

Wenn ich nun nur die Variablenwerte verändere, aber nicht manuell neu zeichnen lasse, sondern dass die Ansicht nur aktulisiert wird, wenn die Methode
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen p1 = new Pen(Color.Blue, 1);
g.DrawEllipse(p1, x, y, 1, 1);
}


aufgerufen wird, funktioniert die Simulation perfekt bis zum Ende. Leider muss ich aber die WindowsForm mit der Hand immer größer und kleiner ziehen, damit panel1_Paint() aufgerufen wird. So kann das Programm aber nur schlecht verwendet werden, da es für den öfteren gebrauch zu aufwendig ist.
Meine Frage also: Wie kann ich panel1_Paint manuell aufrufen? Einfach nur den Inhalt dieser Methode in eine andere kopieren funktioniert natürlich nicht, da ich nicht weis, was ich statt (object snder, PaintEventArgs e) schreiben sollte...

Zudem wäre es interessant zu wissen, wo den nun der Unterschied zwischen
Graphics g = e.Graphics;
Pen p1 = new Pen(Color.Blue, 1);
g.DrawEllipse(p1, x, y, 1, 1);

und
Pen p1 = new Pen(Color.Blue, 1);
panel1.CreateGraphics().DrawEllipse(p1, x, y, 1, 1);


liegt, da man ja mit beiden Varianten Objekte zeichnen kann, die obere aber anscheinend besser funktioniert.


Ich hoffe ich habe mich jetzt besser ausgedrückt und jemandem fällt eventuell etwas ein.


Gruß,
MitgliedXYZ

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

25

23.02.2013, 11:08

Mit panel1.CreateGraphics() erzeugst du ständig ein neues Graphics Objekt, was natürlich wahnsinnig unnötig und ineffizient ist...

1) Zeichne deine Kreise im Paint Event.
2) Verwend dabei das Graphics Objekt der PaintEventArgs.
3) In Zukunft in diesem Forum bitte Code-Tags verwenden.

Meine Frage also: Wie kann ich panel1_Paint manuell aufrufen?

Was, glaubst du, macht Panel1.Invalidate() genau?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (23.02.2013, 11:13)


MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

26

23.02.2013, 11:18

Danke für die schnelle Antwort.

3) In Zukunft in diesem Forum bitte Code-Tags verwenden

Würde ich gerne, aber das Problem wurde hier im Forum schon besprochen, es tritt nicht nur bei mir auf, sondern auch bei vielen anderen. Wenn ich Code-Tages verwende, sind komischerweise alle Leerzeilen verschwunden. Deswegen habe ich den Code stattdessen blau gefärbt.


Was, glaubst du, macht Panel1.Invalidate() genau?

Stimmt, es zeichnet ja Panel1 neu... Da hab ich gar nicht daran gedacht, ich meinte immer es wird einfach nur in den Ursprungszustand versetzt, wie wenn ich beispielsweise das Programm neu starte, daweile ruft es ja Panel1_paint auf. Werde ich gleich mal testen, hab gar nicht gedacht, dass die Lösung so einfach sein könnte...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

27

23.02.2013, 11:33

3) In Zukunft in diesem Forum bitte Code-Tags verwenden

Würde ich gerne, aber das Problem wurde hier im Forum schon besprochen, es tritt nicht nur bei mir auf, sondern auch bei vielen anderen. Wenn ich Code-Tages verwende, sind komischerweise alle Leerzeilen verschwunden. Deswegen habe ich den Code stattdessen blau gefärbt.

Das liegt dann, wie gesagt, vermutlich an deinem Browser und höchstwahrscheinlich einfach nur an der Art und Weise, wie du den Text in deinen Browser reinkopierst. Verwendest du gar vielleicht eine veraltete Version deines Browsers? Verwendest du zum Verfassen eines Postings den Editor- oder den Quellcode-Modus?

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

28

23.02.2013, 11:44

Ich verwende den Editor-Modus, kopiere Texte mit Strg-C von VisualStudio.
Mein Browser ist Google Chrome, ich verwende immer die neueste Version, der Browser updatet sowieso automatisch.

Übrigens könnte der Thread geschlossen werden, mein Problem ist gelöst.
Die Methode Panel1_Paint und die Verwendung von Panel1.Invalidate() sind für meinen Zweck ideal, hab es gerade ausprobiert und es funktioniert so, wie ich es mir vorgestellt habe.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

29

23.02.2013, 11:52

Ich verwende den Editor-Modus, kopiere Texte mit Strg-C von VisualStudio.

Schau mal, ob das Problem im Quellcode Modus auch auftritt und ob es was hilft, wenn du den Text z.B. zunächst in Notepad kopierst und erst von dort dann in den Browser...

Übrigens könnte der Thread geschlossen werden, mein Problem ist gelöst.

Das Schließen eines Thread ist eigentlich eine drastische Maßnahme, die dazu dient, eine völlig außer Kontrolle geratene Diskussion gewaltvoll zu beenden. Aber gut, wenn dein Problem gelöst ist. ;)

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

30

23.02.2013, 13:46

Und es wurde auch bereits an anderer Stelle festgestellt, dass der "Editor"-Modus daran schuld ist. Wenn man den Quellcode-Modus verwendet, hat man das Problem nicht.
hier Mal Beispielhaft einer deiner Codeschnipsel:

C#-Quelltext

1
2
3
4
5
6
private void panel1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    Pen p1 = new Pen(Color.Blue, 1);
    g.DrawEllipse(p1, x, y, 1, 1);
}



Wenn man den Code von beliebiger Stelle in den Editor einfügt, werden die Zeilenumbrüche nicht übernommen. Fügt man nach jedem Zeilenumbruch einen weiteren Zeilenumbruch ein, behält man die Hälfte der Zeilenumbrüche. Kopiert man "funktionierenden" Code aus dem Editor in den Editor, gibt es keine Probleme.
Ich denke, dass das damit zusammenhängt, dass im Hintergrund man im Editor einen "HTML-Editor" hat (man also ein HTML-Element manipuliert) und kein normales Textfeld.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige