Panel wackelt beim verschieben

  • VB.NET

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

    Panel wackelt beim verschieben

    Hallo ich habe ein Problem

    Mein Code:

    VB.NET-Quellcode

    1. Private Sub movingTimer_Tick(sender As System.Object, e As System.EventArgs) Handles movingTimer.Tick
    2. Dim steps As Integer = 20
    3. If GetAsyncKeyState(Keys.S) Or GetAsyncKeyState(Keys.Down) Then
    4. If Panel2.VerticalScroll.Value + steps <= Panel2.VerticalScroll.Maximum Then
    5. Panel2.VerticalScroll.Value += steps
    6. End If
    7. elseIf GetAsyncKeyState(Keys.W) Or GetAsyncKeyState(Keys.Up) Then
    8. If Panel2.VerticalScroll.Value - steps >= Panel2.VerticalScroll.Minimum Then
    9. Panel2.VerticalScroll.Value -= steps
    10. End If
    11. End If
    12. If GetAsyncKeyState(Keys.D) Or GetAsyncKeyState(Keys.Right) Then
    13. If Panel2.HorizontalScroll.Value + steps <= Panel2.HorizontalScroll.Maximum Then
    14. Panel2.HorizontalScroll.Value += steps
    15. End If
    16. ElseIf GetAsyncKeyState(Keys.A) Or GetAsyncKeyState(Keys.Left) Then
    17. If Panel2.HorizontalScroll.Value - steps >= Panel2.HorizontalScroll.Minimum Then
    18. Panel2.HorizontalScroll.Value -= steps
    19. End If
    20. End If
    21. Panel2.Update()
    22. Panel2.Refresh()
    23. End Sub

    Und mein Problem:
    wenn ich mit den Pfeiltasten oder WASD das Panel bewegen möchte, funktioniert das gut, aber manchmal ruckelt es sehr stark. Ich drücke dabei nicht zwei Tasten auf einmal, obwohl ich das Problem ja schon mit ElseIf behoben hätte.
    Weiß jemand, warum?

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

    Lass es...

    Nimm doch nicht KeyAsynchState IM TIMER ?!...

    Dafür gibs KeyDown

    Mach es so:

    VB.NET-Quellcode

    1. Select Case e.KeyCoce
    2. Case Keys.W
    3. Panel1.Top -= 20
    4. Case Keys.S
    5. Panel1.Top += 20
    6. ' usw


    Timer und KeyAsynch => Clusterfuc*


    Und Controls sind nicht für's Animieren da...
    Nimm GDI+

    VB.NET-Quellcode

    1. Dim x As Rectangle


    EDIT:Verwende bitte Option Strict On

    Mfg.eniking1998

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

    Hallo und danke für deine Antwort

    aber:
    1. ich möchte nicht das Panel verschieben (schlecht ausgedrückt von mir), sondern nur die Scrollbalken bewegen.
    2. In dem Panel befindet sich ein Bild, in dem ich mit GDI+ etwas animiere.
    3. eine Frage: funktioniert getKeyCode auch mit mehreren Tasten (z.B. gleichzeitig S und D --> nach rechts unten) ?
    4. noch eine Frage: läuft getKeyCode flüssig, oder muss man für jeden Schritt die Taste neu anschlagen?
    Also,
    wenn Du GDI+ verwendest und im Panel_Paint Ereigniss was malst (hab ich nicht ausprobiert)...
    verwende mal DoubleBuffered = True.

    Das verringert das Flackern des Bildes...


    Und zum 2 Tasten-Thema...

    Benutz mal AndAlso

    Mfg.eniking1998
    hmm. ich sehe nicht, dass man hier OwnerDrawing (GDI) brauchen sollen täte.

    ist doch ok, innem Timer die AutoScrollPosition des Panels zu manipulieren - das sollte auch nicht mehr wackeln, wie wenn man anne Scrollbar zieht.

    Nur mit Panel2.VerticalScroll.Value = blah funzt das nicht - ich weiß auch nicht warum.
    also wennde codeseitig scrollen willst, ist Panel.AutoScrollPositon, .AutoScrollMinsize und so Sachen deine Froinde - und nix anneres.

    Was soll Panel.Update() und Panel.Refresh() in deim Code?
    Nur mal so hingeschrieben, weils nicht abstürzt, oder was? ;)
    Entschuldigung, ich war gerade weg und Mittagessen

    @ErfinderDesRades wie geht das?
    so funktioniert es jedenfalls nicht:

    VB.NET-Quellcode

    1. If GetAsyncKeyState(Keys.S) Or GetAsyncKeyState(Keys.Down) Then
    2. If Panel2.VerticalScroll.Value + steps <= Panel2.VerticalScroll.Maximum Then
    3. Panel2.AutoScrollPosition = New Point(Panel2.AutoScrollPosition.X, Panel2.AutoScrollPosition.Y + steps)
    4. 'Panel2.VerticalScroll.Value += steps
    5. End If
    6. ElseIf ...


    nochmal zur Erinnerung: mit der alten Variante hat es funktioniert! -nur es hat geruckelt :(
    Das Update und Refresh habe ich inzwischen schon rausgenommen, das war nur da, um zu testen, ob es damit besser geht.
    Hallo

    meine Deklaration sieht folgendermaßen aus:

    VB.NET-Quellcode

    1. Private Declare Function GetAsyncKeyState Lib "User32" (ByVal vKey As Integer) As Short


    und zu OptionStrict:
    Ich wusste nicht,dass es das gibt. Habe es dann ausgestellt, und 102 Fehler bekommen. Jetzt habe ich gerade keine Lust, diese zu beheben, werde es aber in Zukunft beachten - in meinen nächsten Projekten.

    phil schrieb:

    Jetzt habe ich gerade keine Lust, diese zu beheben, werde es aber in Zukunft beachten - in meinen nächsten Projekten.
    Schwöre!

    Dann machichmal ne Ausnahme und unterstütze ein Strict Off - Projekt (pfui deibel!!)

    VB.NET-Quellcode

    1. Private Declare Function GetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Keys) As Int16
    2. Private Function IsKeyPressed(ByVal vKey As Keys) As Boolean
    3. Return (GetAsyncKeyState(vKey) And &H8000) = &H8000
    4. End Function
    5. '...
    6. Dim steps = 2
    7. If IsKeyPressed(Keys.S) OrElse IsKeyPressed(Keys.Down) Then
    8. With Panel2.AutoScrollPosition
    9. Panel2.AutoScrollPosition = New Point(-.X, -.Y + steps)
    10. End With
    11. End If
    (sorry - habe heut mein arroganten Tag)
    Zum Verständnis gugge OrElse auf MSDN.
    .AutoScrollPosition ist eiglich völlig irre, also um y zu dekrementieren muss man die Autoscrollposition.Y inkrementieren (erhöhen), und dann von der neuen Position die Inversion an AutoScrollPosition zuweisen.

    Das ist ein Bug, der spottet jeder Beschreibung, aber der ist schon seit VB2003, daher bringen sie das auch nicht mehr in Ordnung.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ja ich schwöre!

    und jetzt zu meinem Programm:
    was ist das mit dem &H8000, das habe ich nie in einem Programmcode gesehen.
    Vielleicht schickst du mir dazu einen Link, weil ich nicht weiß, welchen Suchbegriff ich dazu in Google eingeben soll.

    Und warum ist es eigentlich schlecht mit Panel2.VerticalScroll.Value ?


    [Edit]
    zu dem Bug gerade: meintest du, dass man das nicht direkt zuweisen kann, oder das mit dem Wackeln?
    &8000 ist die hexadezimale Schreibweise von 2^16 - dezimale Schreibung weiß ich grad nicht - rechnes dir selber aus.
    hexadezimale SChreibweise wird gern verwendet, um an einer Zahl das Bitmuster abschätzen zu können, denn And ist hier kein logischer Operator, sondern ein bitweiser Operator (google danach, oder finde es auf MSDN, mittm Verfahren, was in Visual-Studio richtig nutzen für Select Case gezeigt ist)
    &8000 ist das Bitmuster welches genau das '-'-Bit matcht, bei vorzeichenbehafteten Int16.

    mittm Bug meine ich das mit dem Zuweisen an AutoScrollPosition.
    Einen Bug in deim Code hätte ich als Fehler bezeichnet, als Bug bezeichne ich Fehler, die man nicht selbst verbockt hat, sondern annere.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    das heißt, mit dem &H8000 wandelst du quasi von Short in Boolean um - warum kommt da eigentlich ein Short raus?
    --> OptionStrict ON ;)

    aber können wir jetzt bitte wieder zu meinem Problem zurückkommen?

    P.s. das mit dem Converter von VB in C# ist klasse!
    Super, Danke es funktioniert ruckelfrei!

    Lag es jetzt an der AutoScrollPosition?

    enIking1998 schrieb:

    EDIT: Sende mal kompletten Code bitte..

    hier jetzt der fertige Code:

    VB.NET-Quellcode

    1. Private Declare Function GetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Keys) As Int16
    2. Private Sub movingTimer_Tick(sender As System.Object, e As System.EventArgs) Handles movingTimer.Tick
    3. Dim steps As Integer = 20
    4. If IsKeyPressed(Keys.S) OrElse IsKeyPressed(Keys.Down) Then
    5. With Panel2.AutoScrollPosition
    6. Panel2.AutoScrollPosition = New Point(-.X, -.Y + steps)
    7. End With
    8. ElseIf IsKeyPressed(Keys.W) OrElse IsKeyPressed(Keys.Up) Then
    9. With Panel2.AutoScrollPosition
    10. Panel2.AutoScrollPosition = New Point(-.X, -.Y - steps)
    11. End With
    12. End If
    13. If IsKeyPressed(Keys.D) OrElse IsKeyPressed(Keys.Right) Then
    14. With Panel2.AutoScrollPosition
    15. Panel2.AutoScrollPosition = New Point(-.X + steps, -.Y)
    16. End With
    17. ElseIf IsKeyPressed(Keys.A) OrElse IsKeyPressed(Keys.Left) Then
    18. With Panel2.AutoScrollPosition
    19. Panel2.AutoScrollPosition = New Point(-.X - steps, -.Y)
    20. End With
    21. End If
    22. End Sub
    23. Private Function IsKeyPressed(ByVal vKey As Keys) As Boolean
    24. Return (GetAsyncKeyState(vKey) And &H8000) = &H8000
    25. End Function


    Nochmal danke an euch beide, jetzt habe ich auch das mit dem Zitieren kapiert ;)
    es geht auch ein ordentlich Stück kompakter, und v.a. ohne Leerzeilen ohne Sinn:

    VB.NET-Quellcode

    1. Private Sub movingTimer_Tick(sender As System.Object, e As System.EventArgs) Handles movingTimer.Tick
    2. Dim steps As Integer = 20
    3. With Panel2.AutoScrollPosition
    4. If IsKeyPressed(Keys.S) OrElse IsKeyPressed(Keys.Down) Then
    5. Panel2.AutoScrollPosition = New Point(-.X, -.Y + steps)
    6. ElseIf IsKeyPressed(Keys.W) OrElse IsKeyPressed(Keys.Up) Then
    7. Panel2.AutoScrollPosition = New Point(-.X, -.Y - steps)
    8. End If
    9. If IsKeyPressed(Keys.D) OrElse IsKeyPressed(Keys.Right) Then
    10. Panel2.AutoScrollPosition = New Point(-.X + steps, -.Y)
    11. ElseIf IsKeyPressed(Keys.A) OrElse IsKeyPressed(Keys.Left) Then
    12. Panel2.AutoScrollPosition = New Point(-.X - steps, -.Y)
    13. End If
    14. End With
    15. End Sub