NumericUpDown mit rechter Maustaste bedienen

  • VB.NET

Es gibt 40 Antworten in diesem Thema. Der letzte Beitrag () ist von Humax.

    VaporiZed schrieb:

    Zwischenfrage: Warum benutzt Du ein NUD, wenn es nicht macht, was Du willst. Wäre da nicht ein passendes UserControl geeigneter?


    Die Anfangsfrage war ja eigentlich ob ich ein NumericUpDown mit der rechten Maustaste bedienen kann, da wusste ich ja noch nicht, dass es nicht so ganz einfach ist.

    Gonger96 schrieb:

    Was ist denn zu kompliziert an meinem Beispiel? Kann ich da was erklären? Das funktioniert zuverlässig bei jeder Schriftgröße und Textlayout. Sind ja nur ein paar Zeilen.


    Ich hatte den Code gar nicht gesehen, nur deinen Text dazu und da ich Anfänger bin klang (klingt) das zu kompliziert.

    Erst mal Danke an alle bis hier her für eure Mühe, habe jetzt die Tage eher weniger Zeit mich damit auseinander zu setzen und werde wohl erst Mitte der nächsten Woche mich intensiver damit beschäftigen können.
    Aber jetzt doch noch mal die Frage. Mein Code funktioniert doch soweit zuverlässig, da ich ja die Schriftgröße nicht ändere (wenn würde ich die Koordinaten anpassen) oder gibt es noch andere Eventualitäten, die ich jetzt nicht sehe, weshalb der Code z.B. auf einem anderen System so nicht funktionieren könnte?

    Humax schrieb:

    Mein Code funktioniert doch soweit zuverlässig
    Na dann passt's ja. Wir geben ja nur Verbesserungsvorschläge, denn

    Humax schrieb:

    gibt es noch andere Eventualitäten, die ich jetzt nicht sehe, weshalb der Code z.B. auf einem anderen System so nicht funktionieren könnte

    RodFromGermany schrieb:

    Sobald die Schriftgröße geändert wird, z.B. über den Pitch beim System, funktioniert da nix mehr.
    Oder lass es alternatives Design sein. Bildschirmskalierung, Umstellung des NUD, dass die Pfeile links statt rechts sind usw.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Humax schrieb:

    da ich Anfänger bin klang (klingt) das zu kompliziert.
    Lass das NUD wie es ist, denn die Leute, die das Programm bedienen, wissen nicht, dass da Links- und Rechts-Click unterschieden wird.
    Mach Dir ne CheckBox oder mehrere RadioButton neben das NUD, wo Du das Increment gezielt visuell vorgibst.
    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!
    Naja wenn sie sich die Mühe machen den (kurzgehaltenen) Changelog anzugucken wissen sie es.
    Und da sie alle das zugehörige Hauptprogramm bedienen sind sie mit der Verwendung des rechten Mausbuttons in dieser Situation gewöhnt.

    Ich gucke es mir jetzt die Tage nochmal an und entscheide dann ob ich es so lasse, oder evtl doch ein Kontextmenu mache wo man einfach "Increment" einstellen kann.

    Humax schrieb:

    Kontextmenu
    Das steht ja bereits in Post #2, wenn dreist es dort durch ein leeres ersetzt wurde.
    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!
    So ich habe meinen Code jetzt nochmal angepasst. Jetzt lässt sich die "Value"-Eigenschaft mit der rechten Maustaste um den angegebenen Wert ändern, wenn man auf die entsprechenden Pfeile klickt.
    Die Größe des NUD bzw. Schriftgröße / Art wird berücksichtigt. Ist daran jetzt noch was wo ihr sagen würdet, das kann man so nicht lassen bzw. das kann mal Probleme geben?

    VB.NET-Quellcode

    1. Private Sub NUDMouseDown(sender As Object, e As MouseEventArgs) Handles NumericUpDown_SoldierStats.MouseDown, NumericUpDown_Money.MouseDown, NumericUpDown_LevelSelect.MouseDown
    2. If Not e.Button = MouseButtons.Right Then Exit Sub
    3. Dim Nud As NumericUpDown = DirectCast(sender, NumericUpDown)
    4. Dim xMin, xMax, yMinUp, yMaxUp, yMinDown, yMaxDown, RCIncValue As Integer
    5. Select Case Nud.Name
    6. Case "NumericUpDown_Money"
    7. RCIncValue = 1000000
    8. Case "NumericUpDown_SoldierStats"
    9. RCIncValue = 25
    10. Case "NumericUpDown_LevelSelect"
    11. RCIncValue = 5
    12. Case Else
    13. RCIncValue = 1
    14. End Select
    15. For Each cntrl As Control In Nud.Controls
    16. If cntrl.GetType.Name = "UpDownButtons" Then
    17. ' Control gefunden
    18. xMin = Nud.Width - cntrl.Width - 1
    19. xMax = xMin + cntrl.Width - 1
    20. yMinUp = cntrl.Top
    21. yMaxUp = CInt(cntrl.Height / 2)
    22. yMinDown = yMaxUp + 1
    23. yMaxDown = cntrl.Height ' cntrl.Bottom - 1
    24. ' Im Bereich xMin bis xMax und Bereich yMinUp bis yMaxUp bzw. yMinDown - yMaxDown wurde auf die Pfeile geklickt um den Wert zu ändern
    25. If e.X >= xMin AndAlso e.X <= xMax AndAlso e.Y >= yMinUp AndAlso e.Y <= yMaxUp Then ' Wert erhöhen
    26. If Nud.Value + RCIncValue > Nud.Maximum Then
    27. Nud.Value = Nud.Maximum
    28. Else
    29. Nud.Value += RCIncValue
    30. End If
    31. ElseIf e.X >= xMin AndAlso e.X <= xMax AndAlso e.Y >= yMinDown AndAlso e.Y <= yMaxDown Then ' Wert mindern
    32. If Nud.Value - RCIncValue < Nud.Minimum Then
    33. Nud.Value = Nud.Minimum
    34. Else
    35. Nud.Value -= RCIncValue
    36. End If
    37. End If
    38. Exit For
    39. End If
    40. Next
    41. End Sub
    Also das sieht für mich sehr kompliziert aus und nicht unbedingt gut wartbar. Meine Snippet ist kürzer und deutlich einfacher gestaltet. Es macht genau das was von dir gewollt ist. Du kannst den Increment über die Property "LargeIncrement" anpassen und ersparst dir somit diese komische Abfragen.
    Nochmal die Frage: Warum benutzt du das nicht einfach? Gibt es da irgendwas was ich erklären soll?
    Dafür gibt es extra Online Konverter. Ich hab ihn mal für dich konvertiert.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class CustomUpDown
    3. Inherits NumericUpDown
    4. <Category("Data")>
    5. Public Property LargeIncrement As Decimal = 10
    6. Private spinner As Control = Nothing
    7. Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
    8. MyBase.OnHandleCreated(e)
    9. spinner = Controls(0)
    10. AddHandler spinner.MouseClick, AddressOf Spin_MouseClick
    11. End Sub
    12. Private Sub Spin_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
    13. If e.Button <> MouseButtons.Right Then Return
    14. Dim half_height As Integer = Size.Height / 2
    15. If e.Y < half_height Then
    16. Value = Math.Min(Maximum, Value + LargeIncrement)
    17. Else
    18. Value = Math.Max(Minimum, Value - LargeIncrement)
    19. End If
    20. End Sub
    21. End Class

    Das ist eine Klasse. Du fügst eine neue Klasse hinzu und "CustomUpDown.vb" und da kommt es dann rein. Nach dem Kompilieren taucht das CustomUpDown dann in deiner Toolbox auf. Ich würde dir aber empfehlen dich mal mit den Grundlagen zu beschäftigen. Mal angenommen du hättest 20 Numericupdowns auf jeweils 10 Fenstern mit unterschiedlichem Increment, bei einer Klasse hast du da 0 Aufwand. Du gibst im Designer jedem Objekt sein Increment und fertig ;)

    /Edit: Code Tags eingefügt

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

    Humax schrieb:

    Grundsätzlich ziehe ich selbst geschriebenen Code vor.
    Das könnte man als Beratungsresistenz werten.
    Wenn der Code funktioniert und Du ihn verstehst und er deutlich kürzer ist als Deiner sollte doch einer Übernahme nichts im Wege stehen.
    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!
    Ich verstehe nicht wie du so einen Code schreiben kannst, sagst er funktioniert, aber nicht weißt wo er hin soll. Wie hast du ihn dann getestet?
    Gonger hat dir schon vor gefühlten ewigkeiten eine fertige Lösung präsentiert.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.

    RodFromGermany schrieb:

    Das könnte man als Beratungsresistenz werten.
    Wenn der Code funktioniert und Du ihn verstehst und er deutlich kürzer ist als Deiner sollte doch einer Übernahme nichts im Wege stehen.


    Wenn ich sage ich ziehe selbst geschriebenen Code vor, dann möchte ich mich hier nicht missverstanden fühlen. Damit wollte ich ausdrücken, dass es für mich macht es mehr Sinn, mich mit meinem Problem auseinander zu setzen als einen Code zu Übernehmen, nur weil er funktioniert, aber nicht verstehe was er tut.

    Akanel schrieb:

    Ich verstehe nicht wie du so einen Code schreiben kannst, sagst er funktioniert, aber nicht weißt wo er hin soll. Wie hast du ihn dann getestet?
    Gonger hat dir schon vor gefühlten ewigkeiten eine fertige Lösung präsentiert.


    Dann hast du nicht richtig gelesen. Natürlich weiß ich wo MEIN Code hinkommt, wie du richtig anmerkst - wie sollte ich sonst meinen Code testen und sagen können dass er funktioniert...
    Ich bin ja (VB) Anfänger, da wird es wohl erlaubt sein, nicht zu verstehen wie ein C# - Code funktioniert und wo ich den dann hinpacken muss.

    Ich sagte ja bereits, dass ich mich mit dieser Lösung erst Mitte dieser Woche beschäftigen kann.

    --EDIT--
    So habe den Code den Code von @Gonger96 jetzt mal getestet:
    Sie (fast) gut aus. Konnte dadurch auch meinen Code nochmal verbessern.
    Die folgende Zeile müsste man aus zweierlei Gründen noch anpassen:
    1) wegen "Option Strict" von

    VB.NET-Quellcode

    1. Dim half_height As Integer = Size.Height / 2

    in

    VB.NET-Quellcode

    1. Dim half_height As Integer = cint(Size.Height / 2)

    2) Weil sonst an manchen Punkten, mit Linksklick die Value verringert und mit Rechtsklick erhöht wird.

    Code ist soweit auch gut verständlich, bräuchte jedoch Erklärung was diese Zeilen hier machen:

    VB.NET-Quellcode

    1. Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
    2. MyBase.OnHandleCreated(e)
    3. spinner = Controls(0)
    4. End Sub

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

    Dann habe ich das falsch verstanden, sorry.
    Es gibt hier im Forum einen Beitrag der nennt sich "warum die Ausrede das ist C# nicht gilt" oder so ähnlich. Such Mal danach. Vielleicht hilft er dir.
    Und wenn du einen Converter für dich gefunden hast, schmeiß Mal Code von dir rein. Du wirst sehen, das du den Code in C# auch lesen kannst.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    Den Beitrag habe ich sogar in meinen Favoriten gespeichert - aber wohl schon lange nicht mehr beachtet.
    Wenn man die Zeile 14 in @Gonger96 Code wie folgt ändert, dann passt es:

    VB.NET-Quellcode

    1. Dim half_height As Integer = CInt(spinner.Height / 2)


    Wenn mir jetzt noch jemand meine Frage aus #33 beantworten könnte wäre ich sehr dankbar.

    Gonger96 schrieb:


    Zwischenfrage: Da meckert Option Strict? Ist doch Int / Int = Int. Wozu der Cast?


    Weil wenn du Teilen tust auch ein Double rauskommen kann (geht ja nicht immer auf).
    Hier dazu Lektüre: docs.microsoft.com/de-de/dotne…g-point-division-operator

    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen

    Gonger96 schrieb:

    Size.Height ist schon richtig, nicht spinner.Height. So macht Microsoft das auch, habe die Zeile ausm ReferenceSource kopiert.


    In meinem Beispiel (Schriftart und Größe) Microsoft Sans Serif; 72pt) ist size.Height = 116, aber spinner.Height = 114. Dadurch ergibt sich der Bug, das beispielsweise am untersten Punkt des "Pfeil nach oben" - Buttons mit der linken Maustaste der Wert um "Increment" erhöht und mit der rechten Maustaste um "LargeIncrement" verringert wird. mit Spinner. Height ist es richtig.

    Gonger96 schrieb:

    Ist doch Int / Int = Int. Wozu der Cast?


    Int \ Int = Int

    Ein Backslash mach es zu einer Integer-Division, dann ist casten nicht nötig.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin