Grafisches Problem

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Grafisches Problem

    Hi ich hab ein kleines Problem. Und zwar wenn ich ja male auf dem Form, geht ja wenn der Form vollständig aktualisiert wird, das gesamte gepinsel weg.

    Wie behebe bzw. verhindere ich das.

    Wenn jemand nicht weißt was ich meine:

    FreakJNS schrieb:

    du arbeitest ja immernoch mit createGrahics und NICHT im paint-Event. Warum?

    das warum kann ich dir sagen: Ich bin zu doof zum packen :whistling: :whistling:

    Zudem herunterladen, ich hab das jetzt so:

    VB.NET-Quellcode

    1. Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    2. If drawtheory Then
    3. drawNodeTheory(oldtheory, e.Graphics, colorR, colorR)
    4. drawNodeTheory(newtheory, e.Graphics, colorN, colorL)
    5. oldtheory = newtheory
    6. End If
    7. If drawID > -1 Then
    8. drawNodeTheory(oldtheory, e.Graphics, colorR, colorR)
    9. drawNode(nodes(drawID), e.Graphics, colorN, colorL, colorT)
    10. For i As Integer = 0 To nodes.GetLength(0) - 1
    11. If Not nodes(i).calculated Then
    12. drawNode(nodes(i), e.Graphics, colorN, colorL, colorT)
    13. End If
    14. Next
    15. drawID = -1
    16. End If
    17. End Sub
    Dateien
    Dann musst du uns nur noch verraten, wo es weh tut^^
    Neuzeichnen "erzwingen" tust du mit Panel1.Invalidate - musst du nur, wenn sich Daten verändern und du die aktualisierten darstellen willst. Ansonsten passiert das Zeichnen automatisch (z.B. wenn du ein anderes Fenster über deins ziehst werden die entsprechenden Stellen durch automatisches Neuzeichnen wiederhergestellt).
    Das tut weh, wenn ich ein neuen node hinzufüge, dann verschwinden alle anderen nodes. Und allen neuzeichnen wenn ich einen neue mit der Maus setze ist nicht vorstellbar, da die Laufzeit ins bombastische steigen würde.
    ein knoten verbraucht ja schon
    1+1*anzahltDerVerbindungen Rechenschritte. Das würde dann bei 5 noch flüssig gehen
    aber wenn wir von 58 reden sieht es ganz anders aus
    Zum Rechenaufwand: Naja, dann musst du dein Programm anpassen. Immer wenn sich die Daten verändern (also ein neuer Node dazukommt, einer entfernt wird, etc) wird alles durchgerechnet. Ein Node muss dann entsprechende Eigenschaften haben die entsprechend gesetzt werden (Position, Farbe, etc) - im Paint-Event wird anhand dieser Eigenschaften gezeichnet - unabhängig davon was für Berechnungen dahinter stehen. Das geht sehr dann sehr schnell. Es empfiehlt sich vllt eine Art Hüllenklasse zu entwerfen die Darstellungs-Relevante Daten enthält und einen Node - so vermischt sich nicht alles mit der Node-Klasse.

    Außerdem: Trenne Daten von GUI, also "speichere" deine Nodes nicht in der CheckedListbox sondern in einer List(of Node). Die kannst du dann ganz einfach mit Listbox.Datasource = liste daran binden - wie das bei der CheckedListbox bezüglich der Checkboxen funktioniert weis ich nicht, ein besuch bei MSDN sollte helfen^^ So fällt auch das hässliche ReDim weg und dein Code wird viel lesbarer weil du die "For i = 0 to blablabla"-Schleifen durch For-Each-Schleifen ersetzten kannst.

    Zum verschwinden der Nodes: Finde auf den ersten Blick keine Ursache dafür. Genau das ist der Nachteil an deinem Daten-in-Gui-speichern-Code^^ Das bekommst du denke ich aber in den Griff und dann erübrigt sich das Problem denke ich auch sehr schnell.

    Tipp: wenn du soweit bist wirst du im MouseMove-Event ständig ein neuzeichnen auslösen um das sich Bewegene Node darzustellen. Bei mehreren Nodes kann es zu flackern kommen. Abhilfe schafft eine Überladung von .Invalidate: Du kannst angeben welcher Bereich neugezeichnet werden soll. Das ist immer das Bild des Nodes auf der Alten Position und auf der Neuen. Vergleiche diese neuzuzeichnende Fläche mal mit der der gesamten Grafik^^ Ein riesen Performancevorteil.

    Okay, keine Ahnung was du da genau gemacht hast aber das Paint-Event verhält sich bei dir eigenartig. Füge mal ein paar Nodes hinzu und setze Haltepunkte auf das innere der beiden If-Blöcke. Dann schiebe das Fenster aus dem Bildschirm raus und wieder rein. Das Paint-Event wird aufgerufen (wie es soll) aber der Code im inneren der If-Blöcke wird NIE ausgeführt?! Trotzdem werden die Nodes neu gezeichnet.... Hast du eine Erklärung dafür?? Ist mir ein Rätsel....

    Edit: TransparencyKey scheint da iwelche sonderbaren Auswirkungen zu haben. Am besten neues Projekt anfangen und erstmal nur das Zeichnen "üben". Habe sowas seltsames noch nie gesehen - fast wie "AutoRedraw" aus VB6-Zeiten...

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

    Das Paint-Event zeichnet das betreffende Control "aus dem Gedächtnis".
    Alle Informationen, die zum Zeichnen benötigt werden, musst Du in der Klasse bereitstellen und dann mit Invalidate(xx) und Update() ein Neuzeichnen auslösen.
    Wenn Du z.B. im Timertakt ein Quadrat zeichnen willst, musst Du bei 0 alles löschen.
    Bei 1 malst Du die 1. Seite.
    Bei 2 malst Du die 1. und die 2. Seite.
    Bei 3 malst Du die 1., die 2. und die 3. Seite.
    Bei 4 malst Du die 1., die 2., die 3. und die 4. Seite.
    Wahrscheinlich hast Du bei 1 die 1., bei 2 nur die 2., bei 3 nur die 3. und bei 4 nur die 4. Seite gezeichnet.
    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!

    FreakJNS schrieb:

    Zum Rechenaufwand: Naja, dann musst du dein Programm anpassen. Immer wenn sich die Daten verändern (also ein neuer Node dazukommt, einer entfernt wird, etc) wird alles durchgerechnet. Ein Node muss dann entsprechende Eigenschaften haben die entsprechend gesetzt werden (Position, Farbe, etc) - im Paint-Event wird anhand dieser Eigenschaften gezeichnet - unabhängig davon was für Berechnungen dahinter stehen. Das geht sehr dann sehr schnell. Es empfiehlt sich vllt eine Art Hüllenklasse zu entwerfen die Darstellungs-Relevante Daten enthält und einen Node - so vermischt sich nicht alles mit der Node-Klasse.

    in der node klasse gibt es nur gezeichnet und berechnet, also ob dieser gezeichnet wurde, und ob die pfade gezeichnet wurden. Sonst sehen alle nodes gleich aus. Möchte ich einen neuen node setzen ist der bis zum klicken nur theoretisch

    FreakJNS schrieb:

    Tipp: wenn du soweit bist wirst du im MouseMove-Event ständig ein neuzeichnen auslösen um das sich Bewegene Node darzustellen. Bei mehreren Nodes kann es zu flackern kommen. Abhilfe schafft eine Überladung von .Invalidate: Du kannst angeben welcher Bereich neugezeichnet werden soll. Das ist immer das Bild des Nodes auf der Alten Position und auf der Neuen. Vergleiche diese neuzuzeichnende Fläche mal mit der der gesamten Grafik Ein riesen Performancevorteil.

    Geht schlecht bzw. sehe ich kein direkten nutzen, da die pfade ja mit gezeichnet werden. dieser können ja von oben links bis oben rechts gehen.

    FreakJNS schrieb:

    Okay, keine Ahnung was du da genau gemacht hast aber das Paint-Event verhält sich bei dir eigenartig. Füge mal ein paar Nodes hinzu und setze Haltepunkte auf das innere der beiden If-Blöcke. Dann schiebe das Fenster aus dem Bildschirm raus und wieder rein. Das Paint-Event wird aufgerufen (wie es soll) aber der Code im inneren der If-Blöcke wird NIE ausgeführt?! Trotzdem werden die Nodes neu gezeichnet.... Hast du eine Erklärung dafür?? Ist mir ein Rätsel....

    ja weil die werte nur aufgerufen werden, wenn sichd daten verändern. Aber es muss komplett neu gezeichnet werden :)

    FreakJNS schrieb:

    Außerdem: Trenne Daten von GUI, also "speichere" deine Nodes nicht in der CheckedListbox sondern in einer List(of Node). Die kannst du dann ganz einfach mit Listbox.Datasource = liste daran binden - wie das bei der CheckedListbox bezüglich der Checkboxen funktioniert weis ich nicht, ein besuch bei MSDN sollte helfen So fällt auch das hässliche ReDim weg und dein Code wird viel lesbarer weil du die "For i = 0 to blablabla"-Schleifen durch For-Each-Schleifen ersetzten kannst.

    ich nutze ein array das ich per redim verändere. die Checklistbox ist nur zum klicken da, wenn man einen neuen knoten erstellt, das die pfade zu anderen nodes generiert werden :)

    Danke an alle es geht jetzte und ich hab was neues gelernt

    lovelins12 schrieb:

    das ich per redim verändere.
    Nimm eine List(Of...)
    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!