none
Rectangle Eigenschaften zur Laufzeit ändern RRS feed

  • Frage

  • Hallo Freunde und Helfer,

    ich benötige bitte mal wieder Hilfe; offensichtlich ist mein Problem so trivial, dass ich hierfür nicht mal ein Beispiel finde J.

    Folgendes: ich möchte die Eigenschaften eines Rectangle (hier Rect1) zur Laufzeit ändern (Position, Füllfarbe, usw.),  z.B. durch Click auf einen Button oder später auch ein anderes Ereignis (z.B. Timer-gesteuert).

    Wer kann bitte helfen?

    Hier mein bisheriger Code:

    Option Explicit On

    Imports System.Drawing

    Public Class Form2

        Dim Rect1Loc As New Point(100, 130)

        Dim Rect1Size As New Point(New Size(100, 100))

        Dim Rect1 As New Rectangle(Rect1Loc, Rect1Size)

        Dim myPen As New Pen(Color.Black, 2)

        Dim myBrush As Brush = Brushes.DeepPink

        Public Sub DrawRect1(ByVal e As System.Windows.Forms.PaintEventArgs)

            e.Graphics.DrawRectangle(myPen, Rect1)

            e.Graphics.FillRectangle(myBrush, Rect1)

        End Sub

        Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

            DrawRect1(e)

        End Sub

        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) _

    Handles Button1.Click

            'hier soll der Code stehen, der die Rect1-Eigenschaften ändert

             oder die Änderung hervorruft, z.B. eine andere Füllfarbe und/oder Verschiebung des Rect1 um +20

        End Sub

    End Class

    Ich danke allen im Voraus

    Flieger

    Samstag, 7. März 2015 14:41

Antworten

  • Hallo Flieger,

    mal ganz einfach auf Basis Deines Beispiels:

    Imports System
    Imports System.Drawing
    
    Public Class RandomRectangleForm
        Dim someColors() As Color = {Color.Red, Color.Blue, Color.Red, Color.Yellow, Color.Pink, Color.Black}
        Dim PenColor As Color = Color.AliceBlue
        Dim PenWidth As Integer = 2
        Dim BrushColor As Color = Color.DarkOrange
        Dim DrawRectangle As New Rectangle(10, 10, 100, 100)
    
        Dim r As New Random()
        Private Sub Button_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
            ' Führt zum löschen des alten Bereichs (etwas größer um sicher zu gehen)
            DrawRectangle.Inflate(PenWidth, PenWidth)
            Me.Invalidate(DrawRectangle)
    
            ' Andere Farben auswählen
            BrushColor = someColors(r.Next(someColors.Length))
            Do
                PenColor = someColors(r.Next(someColors.Length))
            Loop Until BrushColor <> PenColor
    
            ' Neuen Bereich festlegen
            Dim newRectangle As New Rectangle(r.Next(50) + 10, r.Next(50) + 10, r.Next(50) + 50, r.Next(50) + 50)
            Me.Invalidate(newRectangle)
            DrawRectangle = newRectangle
        End Sub
    
        Private Sub Form_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            Using Brush As New SolidBrush(BrushColor)
                e.Graphics.FillRectangle(Brush, DrawRectangle)
            End Using
    
            Using Pen As New Pen(PenColor, PenWidth)
                e.Graphics.DrawRectangle(Pen, DrawRectangle)
            End Using
        End Sub
    End Class
    

    (Sieht nicht gerade doll aus, sollte aber zeigen wie es gemeint ist).

    Gruß Elmar

    Montag, 9. März 2015 15:19
    Beantworter
  • Hallo Elmar,

    danke für die Hilfe und die Beispiele. Diese haben mich in der Tat auf den richtigen Pfad gebracht. Es war die "rotateAt-Methode", nach der ich gesucht hatte. Nun ist alles klar.....

    Bis zum nächsten Problem :)

    Frohe Ostern

    Gerhard

    Samstag, 4. April 2015 15:07

Alle Antworten

  • Hallo Flieger,

    anstatt Pen und Brush zu speicherm, merke Dir nur die Farbe und erzeuge sie erst beim Zeichnen und gib sie am Ende wieder frei (Dispose). So musst Du Dir nur die Farbe merken und kannst sie beliebig ändern, z. B. via ColorPicker.

    Das Rechteck kannst Du über die eingebauten Methoden wie Inflate verändern oder neu zusammen bauen. Beachte, dass man die Eigenschaften eines Werttypes (Rectangle ist einer) nicht ändern kann, sondern eine neue Instanz des Rectangle erstellen und (hier Rect1) zuweisen muss.

    Was das Neuzeichnen angeht, so geschieht das mit Control.Invalidate. Damit das alte Rechteck gelöscht wird, so rufe Invalidate für den alten Rechtecks-Bereich auf, und Invalidate für den neuen. Windows fasst mehre Aufrufe zusammen, so dass Du dir ein Optimieren an der Stelle sparen kannst.

    Mehr zum Thema: Grafik und Zeichnen in Windows Forms

    Gruß Elmar

    Samstag, 7. März 2015 15:21
    Beantworter
  • Hallo Elmar,

    danke für die schnelle Antwort. Ich habe schon ein wenig probiert. Das mit dem Dispose scheint zu klappen, aber mit den control.invalidate tue ich mich schwer.

    Hast Du vielleicht ein Beispiel, bitte, oder ein Link zu einem solchen? Das wäre etwas anschaulicher.

    Nochmals vielen Dank

    Flieger

    Montag, 9. März 2015 14:38
  • Hallo Flieger,

    mal ganz einfach auf Basis Deines Beispiels:

    Imports System
    Imports System.Drawing
    
    Public Class RandomRectangleForm
        Dim someColors() As Color = {Color.Red, Color.Blue, Color.Red, Color.Yellow, Color.Pink, Color.Black}
        Dim PenColor As Color = Color.AliceBlue
        Dim PenWidth As Integer = 2
        Dim BrushColor As Color = Color.DarkOrange
        Dim DrawRectangle As New Rectangle(10, 10, 100, 100)
    
        Dim r As New Random()
        Private Sub Button_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
            ' Führt zum löschen des alten Bereichs (etwas größer um sicher zu gehen)
            DrawRectangle.Inflate(PenWidth, PenWidth)
            Me.Invalidate(DrawRectangle)
    
            ' Andere Farben auswählen
            BrushColor = someColors(r.Next(someColors.Length))
            Do
                PenColor = someColors(r.Next(someColors.Length))
            Loop Until BrushColor <> PenColor
    
            ' Neuen Bereich festlegen
            Dim newRectangle As New Rectangle(r.Next(50) + 10, r.Next(50) + 10, r.Next(50) + 50, r.Next(50) + 50)
            Me.Invalidate(newRectangle)
            DrawRectangle = newRectangle
        End Sub
    
        Private Sub Form_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            Using Brush As New SolidBrush(BrushColor)
                e.Graphics.FillRectangle(Brush, DrawRectangle)
            End Using
    
            Using Pen As New Pen(PenColor, PenWidth)
                e.Graphics.DrawRectangle(Pen, DrawRectangle)
            End Using
        End Sub
    End Class
    

    (Sieht nicht gerade doll aus, sollte aber zeigen wie es gemeint ist).

    Gruß Elmar

    Montag, 9. März 2015 15:19
    Beantworter
  • Hallo Elmar und andere fleißige Helfer,

    ich war einige Zeit abwesend und bin nun wieder hiermit beschäftigt. Nachdem mir beim o.g. Problem so hervorragend geholfen wurde, bin ich beim nächsten :)

    Das Rechteck (oder ein andere System.Drawing-Object) soll nun gedreht und/oder skaliert und/oder verschoben werden. Ich habe dies mit dem Methoden "RotateTransform", "TranslateTransform" und "ScaleTransform" versucht.

    Dies klappt auch ansatzweise, aber z.B. beim Rotieren wird mit das Objekt gleichzeitig verschoben; es soll aber um den geometrischen Mittelpunkt gedreht/skaliert werden.

       

    'rect1 wurde vorher mit PaintEvent erstellt

    SubrotateRect1()

    Dimg = Me.CreateGraphics

    DimRect2 AsNewRectangle(Rect1.Left, Rect1.Top, Rect1.Width, Rect1.Height)

            g.RotateTransform(10)

            g.DrawRectangle(

    NewPen(Color.Black, 3), Rect2)

           

    Me.Invalidate(Rect1)

            Rect2 = Rect1

            g.Dispose()

    EndSub

    Offensichtlich habe ich bei diesen Methoden Einiges noch nicht verstanden. Kann jemand bitte helfen?

    Vielen Dank im Voraus

    Flieger

    Sonntag, 29. März 2015 15:09
  • Hallo,

    um den "Mittelpunkt" bei einem festzulegen, musst Du ihn via TranslateTransform  festlegen, bei einem Rechteck Width * 0.5f, Height * 0.5f.

    Im übrigen solltest Du nur im Paint Ereignis malen, CreateGraphics außerhalb bringt nichts.

    Einige Beispiele zum "Rumspielen" findest Du u. a. http://www.java2s.com/Code/VB/2D/Catalog2D.htm

    Gruß Elmar

    Sonntag, 29. März 2015 15:35
    Beantworter
  • Hallo Elmar,

    danke für die Hilfe und die Beispiele. Diese haben mich in der Tat auf den richtigen Pfad gebracht. Es war die "rotateAt-Methode", nach der ich gesucht hatte. Nun ist alles klar.....

    Bis zum nächsten Problem :)

    Frohe Ostern

    Gerhard

    Samstag, 4. April 2015 15:07
  • und hier ist es schon, mein nächstes Problem :)

    Wahrscheinlich lässt es sich mit einer Kombination des vorher Gelernten lösen, aber ich komme nicht drauf.

    Folgendes:

    Ich habe ein Polygon erstellt (Valve) und möchte es mit Button-Click derart verändern, dass es um 90° gedreht wird und die Farbe ändert.

    Beides klappt, aber nach der Drehung(Farbänderung bleibt das alte Polygon sichtbar; es soll aber unsichtbar sein oder ganz weg und erst nach dem erneuten Clicken wieder erscheinen. Wie bekomme ich das jeweil nicht benötigte Polygon weg?

    Hier mein bisheriger Code

        Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

            e.Graphics.FillPolygon(ValveBrush, Valve)

            e.Graphics.DrawPolygon(ValvePen, Valve)

            e.Graphics.Dispose()

        End Sub

        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

            SwitchValve()

        End Sub

        Private Sub SwitchValve()

            Dim g = Me.CreateGraphics

            Dim angle As Integer

            If ValveBrush.Color = Color.Black Then

                ValveBrush.Color = Color.White

                angle = 90

            Else

                ValveBrush.Color = Color.Black

                angle = 0

            End If

            ' Rotate um den Mittelpunkt von Valve

            Dim rotatePoint As New Point(vx, vy)

            Dim ValveMatrix As New Matrix

            ValveMatrix.RotateAt(angle, rotatePoint, MatrixOrder.Append)

            g.Transform = ValveMatrix

            g.FillPolygon(ValveBrush, Valve)

            g.DrawPolygon(ValvePen, Valve)

            g.Dispose()

        End Sub

    Kann mir bitte jemand auf die Sprünge helfen?

    Vielen Dank im Voraus

    Grüße

    Flieger

    Samstag, 11. April 2015 13:38
  • Hallo Flieger,

    es ist besser wenn Sie eine neue vollständig verschiedene Frage haben, einen neuen Thread zu machen/öffnen. Damit kann man leichter suchen, finden und sich orientieren.

    Gruß

    Aleksander


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht,  kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Donnerstag, 16. April 2015 07:22