"e.Graphics"-Auswahlrechteck verschieben

  • VB.NET

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von X-Zat.

    "e.Graphics"-Auswahlrechteck verschieben

    Hallo zusammen!

    Hintergrund: (nur für Interessierte, ansonsten unwichtig)
    Ich arbeite gerade an einem eigenen UserControl für das ich "Scrolling" selbst implementieren möchte. Warum ich das selbst machen möchte? Das Control ist ein "Datums-Strahl". In der Mitte befindet sich das aktuelle Datum, links davon die vergangenen Tage, rechtes davon die zukünftigen Tage. Klickt der Benutzer auf ein Datum, dann wird das angeklickte Datum zum mittleren und die übrigen Daten sammeln sich darum herum. Mit dem normalen Scrolling komm ich da nicht weit, weil ich z.B. nicht in einen negativen Bereich scrollen kann.

    Problem:
    Ich habe beobachtet, dass ein Scrollable-Objekt nach dem Scrollen im Paint-Ereignis nicht das ganze Objekt neu zeichnet, sondern nur den neu hinzugekommenen Bereich. Der bereits auf dem Bildschirm befindliche Bereich wird wohl einfach nur verschoben. Das spart natürlich einiges an Ressourcen. Ich würde das gerne auch ressourcenschonend hinbekommen und fragte mich deshalb, ob ich einen rechteckigen Bereich aus meinem e.Graphics-Objekt einfach verschieben kann?
    Ich denke, du hast da etwas nicht ganz zu 100% verstanden...

    Graphics-Objekt: Objekt zum zeichnen von Grafiken.
    Bitmap/Image: Objekt, welches bereits gezeichnetes enthält.

    Mein Tipp: Du hast bestimmt Arrays, Listen o.Ä. womit du deine Daten verwaltest. Nun wird's eigentlich relativ simpel: Bestimme, welches Objekt im Focus/in der Mitte sein soll und rechne die Locations der anderen Daten um. Du musst lediglich festlegen, in welchem Bereich "dazugehörige" Daten mitgezeichnet werden sollen. Zum Beispiel: Die 5 letzten und 5 nächsten des ausgewählten Datums.

    Und das kannst du dann so machen:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. 'Me.Size = New Size(300,100)
    2. Dim g As Graphics = e.Graphics
    3. Dim RectSize As Size = New Size(100,10)
    4. Dim FieldLeft As New Rectangle(New Point(0,50),RectSize) 'Definieren des Datums links/vor des ausgewählten Datums
    5. Dim FieldMid As New Rectangle(New Point(100,50),RectSize) 'Definieren des ausgewählten Datums
    6. Dim FieldRight As New Rectangle(New Point(200,50),RectSize) 'Definieren des Datums links/nach des ausgewählten Datums
    7. g.DrawRectangle(Pens.Black,FieldLeft) 'Der Einfachheit als Rectangles
    8. g.DrawRectangle(Pens.Black,FieldMid)
    9. g.DrawRectangle(Pens.Black,FieldRight)


    Obiges Beispiel ist nur ein statisches Beispiel. Ich würde dem ganzen u.A. eine Zählervariable für den aktuellen Index meiner Daten und eine Variable für die Angabe der Abweichung der Zeichnungen von links und rechts wegen des Scrollings hinzufügen.
    Aber die Technik ist entscheidend. Und ich bin ehrlich gesagt zu faul und finde es nicht korrekt, jetzt einen wahrscheinlich recht langen Code zurecht zu basteln und hier für C&P reinzustellen...

    MfG,
    XZat / Momo
    Dank für für deinen Beitrag. Anscheinend hatte ich das Graphics-Objekt wirklich noch nicht ganz verstanden. Ich glaub, jetzt hab ich's aber verstanden.

    Das Problem drehte sich allerdings trotzdem ein wenig um was anderes:
    Angenommen, ich habe ein scrollfähiges Container-Objekt mit einem übergroßem Bild drin, sodaß man scrollen muss, um den unteren Teil des Bildes erkennen zu können. Wenn der Benutzer jetzt 1 Pixel nach unten scrollt, dann wird natürlich das Paint-Ereignis des Conrols ausgelöst. Im Paint-Ereignis wird allerdings nur vom Code verlangt, dass diese 1-Pixel-Reihe neu gezeichnet wird. Der Code zeichnet also nur diese eine Pixelreihe und von Zauberhand verschiebt sich der weitere Teil des Bildes einfach um ein Pixel nach oben, sodaß der Bildausschnit vollständig gezeichnet ist. Effizienter gehts nicht.

    Und genau das ist das, was ich nicht ganz verstehe. Ich will das auch so machen, dass ich nur diese eine Pixel-Reihe neu zeichne. Wenn ich das "Scrolling" aber selbst implementiere, dann muss ich den ganzen Bereich neu zeichnen... Mir kommt es fast so vor, als würde das Betriebssystem das Scrollen irgendwie möglich machen. Und deshalb frage ich mich, ob ich das auch so effizient hinbekommen kann...

    Ich hoffe, ich konnte mich halbwegs klar ausdrücken... :)
    Eigentlich wird dann nur mit SourceRectangles gearbeitet...

    Beispiel: Du hast einen 100x100 Pixel großen Container und eine 200x200 Pixel große Bitmap. Es werden nur 100x100 Pixel angezeigt werden können.
    Mit GDI kannst du bei ".DrawImage" (davon weiß ich es sicher) ein Parameter übergeben, welches sich mit der Angabe einer SourceRectangle einen Bestimmten Bereich aus einem Bild holt und in das ebenfalls mit übergebene DestinationRectangle zeichnet.
    Heißt: Eine Bitmap global (z.B. innerhalb eine Klasse) freihalten, ei Ändern des Inhaltes des Containers (z.B. Neues Datum, nicht aber Bewegung) einfach in diese Bitmap den kompletten Inhalt des Controls zeichnen und bei jedem Paint das SourceRectangle neu einstellen und dann stumpf mit ".DrawImage" diese Bitmap mit der Angabe von Source- und DestinationRectangle zeichnen.

    Müsste gehen...

    MfG,
    X-Zat / Momo