GDI+ permanent Zeichnen während der Laufzeit

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    GDI+ permanent Zeichnen während der Laufzeit

    Hey,
    ich möchte gerne während der Laufzeit Elemente auf die Form zeichnen.
    Nehmen wir mal an, ich möchte bei einem Button-Klick etwas permanent Zeichnen.
    Wie kann ich das lösen?

    Beispiel: Ich habe eine Liste mit Bildpfaden die ich per Buttonklick auslese und dann anschließend auf die Form zeichnen möchte.
    Wie ich im Button-Klick Event zeichne, weiß ich ja. Ist ja nicht wirklich anders als im OnPaint Event. Allerdings ist es dann ja nicht permanent.

    Lg
    ...aber gut, dass wir darüber gesprochen haben!
    Deswegen soll man ja nur im Paint-Event zeichnen - alles annere ist nicht permanent.
    Das ist bisserl aufwändig, du musst nämlich etwas bereitstellen, damit jederzeit die Zeichnung ausgeführt werden kann.
    ich code dafür immer "Figure" - Klassen, wo alles nötige drin ist.
    Dann kann ich auch eine List(Of Figure) anlegen, denn meist will man mehrere Objekte zeichnen.
    Sieh mal zu, ob du bei activevb.de/cgi-bin/tippupload…beweglicher_Figur_darstel durchsteigst

    Sonderzeichen schrieb:

    permanent Zeichnen
    So was:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private flag As Boolean = False
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. flag = True
    5. Me.Invalidate()
    6. End Sub
    7. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    8. flag = False
    9. Me.Invalidate()
    10. End Sub
    11. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    12. If flag Then
    13. e.Graphics.DrawString("Klick", New Font("Arial", 20, FontStyle.Bold), Brushes.Black, New Point(50, 50))
    14. End If
    15. End Sub
    16. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @ErfinderDesRades
    Danke, ich werds mir durchlesen und später Rückmeldung geben.

    @RodFromGermany
    Damit ich das so lösen kann, müsste ich den gesammten Code den ich brauche in das OnPaint-Event schreiben, was ein wenig unsauber wäre :/
    Ich habe eine eigene Sub dafür.

    Könnte man nicht in einer Sub beispielsweise das OnPaint Event aufrufen und quasi etwas während der Laufzeit einfügen?
    Mein genaueres Vorhaben ist, dass ich jederzeit das gezeichnete entfernen und neu Zeichnen kann.
    Ich gehe im Script nämlich die Drives durch und möchte zu jedem Drive ein entsprechendes Bild aus den Resourcen zeichnen.
    Ich habe schon überlegt, das ganze mit Controls zu machen, sprich:
    Panel
    -> Picturebox
    -> Label
    So kann ich auch entsprechende Events leicht darauf handeln. Wäre das eine gute Idee? Wie würde es mit der Performance aussehen?
    ...aber gut, dass wir darüber gesprochen haben!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Sonderzeichen“ ()

    Sonderzeichen schrieb:

    Damit ich das so lösen kann, müsste ich den gesammten Code den ich brauche in das OnPaint-Event schreiben, was ein wenig unsauber wäre
    Ich habe eine eigene Sub dafür.
    Wohl wahr. Was ich dir nahezubringen versuche ist, dass ein Sub dafür nicht hinreicht, sondern du brauchst ein Class dafür. Denn ein Sub kann sich zB nicht merken, wo die Zeichnung auszuführen ist.

    Sonderzeichen schrieb:

    Könnte man nicht in einer Sub beispielsweise das OnPaint Event aufrufen und quasi etwas während der Laufzeit einfügen?
    Man kann vieles, nur sinnvoll ist das nicht.
    Vorgesehen ist, dass Control.Invalidate(Rectangle) aufgerufen wird - daraufhin löscht das Control dieses Rechteck und feuert dann das Paint-Event, wo du deine Zeichnung in diesem Rechteck ausführen kannst.

    Sonderzeichen schrieb:

    etwas während der Laufzeit einfügen
    geht schlecht.
    Aber Du kannst aus dem Paint-Event heraus eine Sub aufrufen mit dem Parameter e.Graphics, wo dann die Sub reinmalen kann.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    geht schlecht.

    Geht schon, hab das so zuvor immer gelöst, wird aber bei vielen Items dann irgendwann nicht mehr flüssig und man sieht teils wie die Controls nach dem erstellen kurz nach flackern. (Oder kommt einfach nur meine Grafikkarte damit nicht klar?)

    Naja. Ich bin nun soweit, dass ich Zeichnen kann, jedoch verstehe ich Me.Invalidate leider noch nicht richtig. Ich habe bisher noch nicht genau verstanden, was die Parameter sein müssen.

    Gibt es für GDI+ (Im bezug auf Controls, normal einfach rum malen ist ja total easy) ein gutes Tutorial, das erklärt wie man beispielsweise eine Progressbar oder ähnliches manipuliert, ich denke zumindest mal, dass eine Progressbar recht einfach für den Start ist. Oder nicht? Würde mich freuen, wenn ihr mich auf ein gutes Anfängertutorial verweisen könntet, aus dem ich auch lernen kann und welches man auch in anderen Controls oder später auch eigene Controls gut anwenden kann.

    Ich bin darin nämlich noch leider nicht erfahren :/.

    Lg
    ...aber gut, dass wir darüber gesprochen haben!

    Sonderzeichen schrieb:

    Ich bin darin nämlich noch leider nicht erfahren
    Dafür hast Du allerdings recht klare Vorstellungen, was machbar ist. Kommst Du von C++?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Dafür hast Du allerdings recht klare Vorstellungen
    Ist das Ironie?
    Erst willer Bilder auf ein Form malen, nun will er eine "Progressbar oder ähnliches" in nicht näher beschriebener Weise "manipulieren"...

    Ich bin ja gespannt, ob er den ObjectBrowser findet und nutzen kann...
    Und ob er letztlich am Begriff "Überladung" scheitert - wie so viele...
    Weil Invalidate ist ja überladen.

    ErfinderDesRades schrieb:

    Dann guck mal im ObjectBrowser nach, was die Parameter sein müssen.

    Danke für den Hinweis, hab den ganz vergessen... (facepalm). Ist echt Hilfreich ;).

    RodFromGermany schrieb:

    Kommst Du von C++?

    Nein, habe noch nie mit C++ gearbeitet, habe jedoch ironischerweise ein C++ Referenzbuch direkt neben meinem Schreibtisch stehen :D.

    ErfinderDesRades schrieb:

    Ich bin ja gespannt, ob er den ObjectBrowser findet und nutzen kann...

    Jup, F2, wenn du den meinst. Oder meinst du etwas anderes?

    Ich hab mir inzwischen eine Klasse gemacht, welche von UserControl erbt. Anschließend einige Properties hinzugefügt die logischerweise bearbeitet werden können und anschließend das OnPaint Event überschrieben. Also im OnPaint Event wird halt der gesammte Code ausgeführt, der alles anzeigt und so. Außerdem entscheide ich im OnPaint Event, welches Bild beispielsweise aus den Resourcen geladen und mit e.Graphics Element aus dem OnPaint Event gezeichnet wird. Ist das so richtig oder hab ich irgendwas wichtiges vergessen?

    Achso, was genau kommt eigentlich in das New() Event? Dort steht standardmäßig Initialize.. drin. Gibts noch andere wichtige sachen die da rein gehören?

    Lg
    ...aber gut, dass wir darüber gesprochen haben!

    Sonderzeichen schrieb:

    Ich hab mir inzwischen eine Klasse gemacht, welche von UserControl erbt.
    Für sowas ist UserControl nicht da.
    Auch ist das erstmal noch ühaupt nicht nötig.
    Was ich dir nahezubringen versuche, ist, dass du eine Klasse schreibst, die, wenn man ihr ein Graphics-Objekt übergibt, sich darin zeichnen kann.
    Eine solche Klasse kann mit jedem Control interagieren - auch mit einem Form.
    Von so einer Klasse kannst du dann auch viele instanzieren, und dann hast du viele Figuren, die sich mw. auf einem Form zeichnen können.
    Das was du da mit dem UserControl versuchst, ist eine Art "Canvas" - ein spezialisiertes Control, auf dem sich Figure-Klassen zeichnen können, und mit dem man die Figure-Objekte vlt. besonders geschickt verwalten kann.
    Wie gesagt: Ist erstmal noch ühaupt nicht dran, denn du hast noch immer keine Figure-Klasse.
    Ein anneres Beispiel ist vlt. StoryCards - verschiebbare Zeichenobjekte
    Da ist das mit den Figuren und dem Canvas so einigermassen umgesetzt.

    Und nocheinmal:
    1. ein Canvas ist noch nicht dran - bring erstmal Figure-Klassen ans laufen, die sich einfach auf einem Form zeichnen
    2. UserControl ist suboptimal als Basisklasse für ein Canvas. Für ein Canvas reicht einfach Control als Basisklasse