Formfehler

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von TheVBTutorialsVB.

    Formfehler

    Hallo Forum,

    ich habe ein Programm geschrieben, bei dem ein Kreis bewegt werden kann, und an den Rändern der Form "stoppt".
    Ich habe ein Rectangle angegeben, in dem sich der Kreis bewegen darf und dieses Rectangle die Größe der Form zugewiesen.
    Die Formgröße ist 800;600, aber wenn ich jetzt starte und dem Kreis sage, dass dieser stoppen soll, hält er nur außerhalb der Form.
    Ich habe mir die Position in einer Konsole ausgeben lassen, vielleicht hat jemand eine Idee. Hier der Code:


    Spoiler anzeigen

    Klasse Kreis:

    VB.NET-Quellcode

    1. Public Class Kreis
    2. Private r As Integer
    3. Private p As Point
    4. Public Sub New(ByVal radius As Integer, ByVal position As Point)
    5. r = radius
    6. p = position
    7. End Sub
    8. Public Property Position As Point
    9. Get
    10. Return p
    11. End Get
    12. Set(value As Point)
    13. p = value
    14. End Set
    15. End Property
    16. Public Property Radius As Integer
    17. Get
    18. Return r
    19. End Get
    20. Set(value As Integer)
    21. r = value
    22. End Set
    23. End Property
    24. Public Sub Draw(ByVal e As System.Windows.Forms.PaintEventArgs)
    25. e.Graphics.DrawEllipse(Pens.Black, New Rectangle(p, New Size(r * 2, r * 2)))
    26. End Sub
    27. End Class


    Klasse Form:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <DllImport("kernel32", SetLastError:=True)> _
    4. Private Shared Function AllocConsole() As Boolean
    5. End Function
    6. <DllImport("kernel32", SetLastError:=True)> _
    7. Private Shared Function FreeConsole() As Boolean
    8. End Function
    9. Private k As New Kreis(50, New Point(50, 50))
    10. Private r As Rectangle
    11. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    12. AllocConsole()
    13. Console.WriteLine("-Programm gestartet-" & vbNewLine)
    14. Console.WriteLine("X: " + CStr(k.Position.X.ToString) + " Y: " + CStr(k.Position.Y))
    15. Console.WriteLine("Startet mit Radius: " + CStr(k.Radius))
    16. Me.Width = 1000
    17. Me.Height = 800
    18. r = New Rectangle(New Point(0, 0), New Size(Me.Width - 120, Me.Height - 140))
    19. End Sub
    20. Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    21. Select Case e.KeyCode
    22. Case Keys.W
    23. If k.Position.Y > r.Y Then
    24. k.Position = New Point(k.Position.X, k.Position.Y - 5)
    25. Me.Invalidate()
    26. Console.WriteLine("X: " + CStr(k.Position.X.ToString) + " Y: " + CStr(k.Position.Y))
    27. End If
    28. Case Keys.S
    29. If k.Position.Y < r.Height Then
    30. k.Position = New Point(k.Position.X, k.Position.Y + 5)
    31. Me.Invalidate()
    32. Console.WriteLine("X: " + CStr(k.Position.X.ToString) + " Y: " + CStr(k.Position.Y))
    33. End If
    34. Case Keys.D
    35. If k.Position.X < r.Width Then
    36. k.Position = New Point(k.Position.X + 5, k.Position.Y)
    37. Me.Invalidate()
    38. Console.WriteLine("X: " + CStr(k.Position.X.ToString) + " Y: " + CStr(k.Position.Y))
    39. End If
    40. Case Keys.A
    41. If k.Position.X > r.X Then
    42. k.Position = New Point(k.Position.X - 5, k.Position.Y)
    43. Me.Invalidate()
    44. Console.WriteLine("X: " + CStr(k.Position.X.ToString) + " Y: " + CStr(k.Position.Y))
    45. End If
    46. Case Keys.Add
    47. k.Radius += 1
    48. Me.Invalidate()
    49. Console.WriteLine("Radius: " + CStr(k.Radius))
    50. Case Keys.Subtract
    51. k.Radius -= 1
    52. Me.Invalidate()
    53. Console.WriteLine("Radius: " + CStr(k.Radius))
    54. End Select
    55. End Sub
    56. Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    57. k.Draw(e)
    58. End Sub
    59. End Class



    Grüße,

    TheVBTutorialsVB

    @TheVBTutorialsVB: Dein Algorithmus macht Mist, sobald Du den Durchmesser des Kreises veränderst.
    Bei einer Durchmesseränderung musst Du das Rectangle neu berechnen und ggf. auf Kreis-außerhalb reagieren.
    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!
    das wird letztlich vom Betriebssystem aufgerufen, welches erkennt, wann ein Bildschirmbereich neu zu zeichnen ist.

    Bei OwnerDrawing teilt mans dem OS dann explizit mit, wenn man einen Bereich neugezeichnet haben will, durch Control.Invalidate().

    Das ist hier übrigens sehr unperformant umgesetzt, man würde besser genau das Rectangle angeben, was ungültig ist, anstatt das ganze Control zu invalidieren.
    gugge ObjectBrowser und MSDN zu Invalidate() und seine Überladungen.

    @TheVBTutorialsVB:: Was machst du da eiglich mit AllocConsole() und FreeConsole()?

    ErfinderDesRades schrieb:

    AllocConsole() FreeConsole()
    Wohl ursprünglich von mir, um mit Console.WriteLine() Testausgaben machen zu können.
    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: Ja, das habe ich vor kurzem bei dir gesehen und fand es sehr nützlich. Die Änderung des Durchmessers habe ich entfernt, brauche es doch nicht, aber danke für den Hinweis.
    @sonne75: Ich zeichne in der Form1_Paint, was gezeichnet wird steht in der Kreisklasse.
    @ErfinderDesRades: Ich hab den ObjectBrowser zwar noch nie benutzt, aber ich probiers mal.

    Danke für alle Antworten, ich probier es aus.