Simple (If-Else) Anweisungen funktionieren nicht richtig?

  • WPF

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von SKeks.

    Simple (If-Else) Anweisungen funktionieren nicht richtig?

    Hallo,
    Vorweg ich bin ein mehr ein PHP-Programmierer (Hobbymäßig) und habe in Sachen VB oder XAML noch nicht so Richtig die Kenntnis deshalb möchte ich euch bitte etwaige Fehler worüber Profis nur lachen können zu Verzeihen ;)

    Zu meinem Problem.
    Ich habe schon sehr Erfolgreich ein kleines Programm (oder mehr ein Tool) geschrieben was so auch Funktioniert.
    Nun Möchte ich aber eine Art Textbox "Validation" einfügen auf kompletter Custom Basis. Ich habe mir dafür direkt eine Art "Popup bzw. Modal Window" in XAML gebaut welches ich einfach Anzeigen lassen Möchte was soweit ja auch Funktioniert.
    Doch nun zu meinem Problem. Wie ihr im Codeabschnitt sehen könnt wende ich (wie ich es in PHP schon sehr erfolgreich Anwende) relativ einfache If-Else Abfragen an um zu Prüfen ob etwas Richtig ist oder nicht.
    Hier in meinem Beispiel Frage ich ab ob der Wert in der Min. und Max. Textbox den gleich oder der Wert in der Min. größer ist als die Max. Textbox.
    Doch Wenn ich jetzt in die Min. Textbox 9 eintrage und in die Max. Textbox 20 dann sagt er "Min. darf nicht größer oder gleich als Max. sein!" was es ja im Grunde gar nicht ist da 9 ja bekanntlich kleiner als 20 ist.
    Wenn ich jedoch Min. 10 und Max. 20 eingebe dann klappt es.

    Wo ist da nun jetzt der Fehler?

    PS: Wenn "checkError = 0" also alles passt dann wird ein Separater Codeabschnitt ausgeführt der die Werte in den Textboxen speichert.

    VB.NET-Quellcode

    1. Private Sub checkErrors()
    2. If terrainToolMinRadius_tb.Text >= terrainToolMaxRadius_tb.Text Then
    3. gridMain.IsEnabled = False
    4. gridMain_blur.Radius = 10
    5. gridError.Visibility = Visibility.Visible
    6. error_title.Content = "Window Title"
    7. error_text.Text = "Min. darf nicht größer oder gleich als Max. sein!"
    8. checkError = 1
    9. ElseIf terrainToolMinRadius_tb.Text < 1 Then
    10. gridMain.IsEnabled = False
    11. gridMain_blur.Radius = 10
    12. gridError.Visibility = Visibility.Visible
    13. error_title.Content = "Window Title"
    14. error_text.Text = "Min. darf nicht kleiner als 1 sein!"
    15. checkError = 1
    16. ElseIf terrainToolMinStrength_tb.Text >= terrainToolMaxStrength_tb.Text Then
    17. gridMain.IsEnabled = False
    18. gridMain_blur.Radius = 10
    19. gridError.Visibility = Visibility.Visible
    20. error_title.Content = "Window Title"
    21. error_text.Text = "Min. darf nicht größer oder gleich als Max. sein!"
    22. checkError = 1
    23. ElseIf terrainToolMinStrength_tb.Text < 1 Then
    24. gridMain.IsEnabled = False
    25. gridMain_blur.Radius = 10
    26. gridError.Visibility = Visibility.Visible
    27. error_title.Content = "Window Title"
    28. error_text.Text = "Min. darf nicht kleiner als 1 sein!"
    29. checkError = 1
    30. Else
    31. checkError = 0
    32. End If
    33. End Sub


    Ich hoffe ihr könnt mir weiter helfen :)
    Willkommen im Forum.
    Das Problem ist, dass zwar 9 < 20, aber nicht "9" < "20", da bei einem String-Vergleich (und genau das machst Du in Zeile#2, denn .Text gibt nun mal einen String, also Text wieder) die Zeichen nacheinander verglichen werden. Und "9" kommt nun mal nach "2", ist also größer. Die "0" hinter der "2" interessiert dann den Compiler nicht mehr. Wandle vorher die Strings in Zahlen um* (und stell sicher, dass in den TextBoxen wirklich Zahlen drinstehen), dann klappt es auch mit der Nachbarin dem Vergleich.

    *Double.Parse(terrainToolMinRadius_tb.Text) macht aus dem Text der angegebenen TextBox eine Kommazahl.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Ich habe es mittlerweile so gemacht das man nur Zahlen eingeben kann ;)

    XML-Quellcode

    1. <TextBox x:Name="terrainToolMinStrength_tb" Style="{StaticResource textbox}" Text="&lt;min&gt;" Width="30" Margin="0,8,0,0" HorizontalAlignment="Left" MaxLength="3" PreviewTextInput="NumberValidation" />


    VB.NET-Quellcode

    1. Private Sub NumberValidation(ByVal sender As Object, ByVal e As TextCompositionEventArgs)
    2. Dim regex As Regex = New Regex("[^0-9]+")
    3. e.Handled = regex.IsMatch(e.Text)
    4. End Sub


    Ich muss jetzt nur noch raus finden wie es geht das man mindestens einen Punkt (als Kommastelle) eingeben kann

    Stollejay schrieb:



    Ich muss jetzt nur noch raus finden wie es geht das man mindestens einen Punkt (als Kommastelle) eingeben kann


    Quellcode

    1. \d+\.?\d+


    Würde heißen eine oder mehr zahlen, OPTIONAL ein Punkt wegen decimal und dann muss eine zahl oder mehr folgen.
    sowas hier wäre also valid:

    123123
    12312.123123
    1.1
    0.21123123

    invalid wäre:
    .112312312
    0.
    und negativ zahlen.
    Grüße , xChRoNiKx
    Hatte ganz vergessen das ich es Mittlerweile auch mit dem Punkt geschafft habe:

    VB.NET-Quellcode

    1. Dim regex As Regex = New Regex("[^0-9+\.]")


    Zwar hätte ich dort gern nur Maximal einen Punkt aber irgendwie will das nicht funktionieren. Auch mit:

    VB.NET-Quellcode

    1. Dim regex As Regex = New Regex("[^0-9+\.{1}]")

    nicht. Aber ganz so schlimm ist das nicht.

    @ErfinderDesRades:
    Das habe ich mittlerweile auch gelesen. Das ^ am Anfang definiert das NICHT ERLAUBT. Wenn ich das jedoch weg lasse bzw. es so umbaue dann kann ich wieder alles eingeben statt nur Zahlen ;)
    Jedoch klappt das so irgendwie das nur Zahlen eingegeben werden dürfen.

    Trotzdem vielen vielen Dank für eure Antworten :)

    Edit:
    Ich habe nun noch ein Problem welches erst jetzt so Richtig in den Vordergrund kommt. Und zwar kommt bei den If-Else Abfragen nur immer eine Fehlermeldung egal wie viel Textboxes den Falschen Wert haben.
    Ich habe die Abfragen mittlerweile etwas Umgebaut weil ich es eben auch so ähnlich in PHP habe und gedacht habe das es doch so hier auch gehen müsste aber Pustekuchen :D

    VB.NET-Quellcode

    1. Dim checkError As Boolean = True
    2. Private Sub checkErrors()
    3. Dim millisPerDay As Integer = Integer.Parse(millisPerDay_tb.Text)
    4. Dim terrainToolMinRadius As Integer = Integer.Parse(terrainToolMinRadius_tb.Text)
    5. Dim terrainToolMaxRadius As Integer = Integer.Parse(terrainToolMaxRadius_tb.Text)
    6. Dim terrainToolMinStrength As Integer = Integer.Parse(terrainToolMinStrength_tb.Text)
    7. Dim terrainToolMaxStrength As Integer = Integer.Parse(terrainToolMaxStrength_tb.Text)
    8. If millisPerDay < 1000 Then
    9. checkError = False
    10. gridMain.IsEnabled = False
    11. gridMain_blur.Radius = 10
    12. gridError.Visibility = Visibility.Visible
    13. error_title.Content = millisPerDay_label_text(Lang)
    14. error_text.Text = millisPerDay_label_text(Lang) & " darf nicht weniger als 1000 sein!"
    15. End If
    16. If terrainToolMinRadius >= terrainToolMaxRadius Then
    17. checkError = False
    18. gridMain.IsEnabled = False
    19. gridMain_blur.Radius = 10
    20. gridError.Visibility = Visibility.Visible
    21. error_title.Content = "Window Title"
    22. error_text.Text = "Min. darf nicht größer oder gleich als Max. sein!"
    23. End If
    24. If terrainToolMinRadius < 1 Then
    25. checkError = False
    26. gridMain.IsEnabled = False
    27. gridMain_blur.Radius = 10
    28. gridError.Visibility = Visibility.Visible
    29. error_title.Content = "Window Title"
    30. error_text.Text = "Min. darf nicht kleiner als 1 sein!"
    31. End If
    32. If terrainToolMinStrength >= terrainToolMaxStrength Then
    33. checkError = False
    34. gridMain.IsEnabled = False
    35. gridMain_blur.Radius = 10
    36. gridError.Visibility = Visibility.Visible
    37. error_title.Content = "Window Title"
    38. error_text.Text = "Min. darf nicht größer oder gleich als Max. sein!"
    39. End If
    40. If terrainToolMinStrength < 1 Then
    41. checkError = False
    42. gridMain.IsEnabled = False
    43. gridMain_blur.Radius = 10
    44. gridError.Visibility = Visibility.Visible
    45. error_title.Content = "Window Title"
    46. error_text.Text = "Min. darf nicht kleiner als 1 sein!"
    47. End If
    48. End Sub


    Ich würde das gern so machen wollen das wenn Beispielsweise terrainToolMinRadius < 1 UND terrainToolMinStrength < 1 sind dann soll entweder eine "Fehlermeldung" nach der anderen auf gehen (so hätte ich es ja jetzt wenn es gehen würde) oder eben das die 2 Texte in nur einer Fehlermeldung stehen (Untereinander).
    Aber wie gesagt: Das nun letzte Problem ist jedoch das immer nur die erste oder letzte Fehlermeldung erscheint (je nachdem welche Textbox den Falschen Wert hat).

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Stollejay“ ()

    oder eben das die 2 Texte in nur einer Fehlermeldung stehen (Untereinander).

    Liste deine Fehlerausgaben vorher in einer extra Stringvariablen auf und gib zum Schluss diesen String einfach in der Fehler-TextBox aus...

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

    @Stollejay Pack mal jede Deiner Variablen in einen solchen Konstrukt:

    VB.NET-Quellcode

    1. If a < GrenzeUnten OrElse a >= GrenzeOben Then
    2. ' was tun
    3. End If
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Keine Veränderung der Fehlermeldungen.
    Wenn zb. terrainToolMinRadius >= terrainToolMaxRadius ist UND terrainToolMinStrength >= terrainToolMaxStrength ist zeigt er mir dennoch immer nur eine Fehlermeldung (meist die von: terrainToolMinStrength >= terrainToolMaxStrength) an statt erst die erste und dann die Zweite.

    Irgendwas muss ich hier in VB übersehen. Ich frage mich nur was.

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

    @Stollejay wenn mehrere Out-Of-Range-Bedingungen gekoppelt untersucht werden sollen, musst Du sie zunächst gruppieren:
    Mach Dir ein Enum-Flag und setze Dir die Variable zusammen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. <Flags>
    3. Enum Größe
    4. Nix = 0
    5. Länge = 1
    6. Breite = 2
    7. Höhe = 4
    8. Fläche = Länge Or Breite
    9. Volumen = Länge Or Breite Or Höhe
    10. End Enum
    11. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    12. Dim x = 15
    13. Dim y = 16
    14. Dim z = 17
    15. Dim fehler As Größe = Größe.Nix
    16. If x < 10 Or x > 12 Then fehler = fehler Or Größe.Länge
    17. If y < 10 Or y > 12 Then fehler = fehler Or Größe.Breite
    18. If z < 10 Or z > 12 Then fehler = fehler Or Größe.Höhe
    19. MessageBox.Show(fehler.ToString)
    20. Select Case fehler
    21. Case Größe.Nix
    22. ' was tun
    23. Case Größe.Länge
    24. ' was tun
    25. Case Größe.Fläche
    26. ' was tun
    27. Case Größe.Volumen
    28. ' was tun
    29. End Select
    30. End Sub
    31. End Class
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Du übersiehst, dass Du in Post#8 in all Deinen Fehlertextzuweisungen (Zeile#18, #28, #38, #48, #58) der Fehlertextvariablen immer neuen Text zuweist, das heißt, den alten Wert über Bord wirfst und neuen Text reintust. Du überschreibst also die bisher in der "Variablen" error_text.Text bereits enthaltenen Werte. Angenommen, alle Bedingungen würden zutreffen, dann würde erst der Fehlertext aus Zeile#18 in error_text.Text reingeschrieben. In error_text.Text würde dann stehen: "blablabla darf nicht weniger als 1000 sein!". Dann wird Zeile#28 erreicht. Wieder eine Zuweisung an error_text.Text. ABER! Der Text, der schon drinsteht, wird überschrieben und durch "Min. darf nicht größer oder gleich als Max. sein!" ersetzt. Das ist das gleiche als wenn Du schreibst:

    VB.NET-Quellcode

    1. Dim i As Integer = 0
    2. i = 1
    3. i = 2
    4. i = 3

    Da wird i am Ende auch nur 3 sein und die anderen Werte "vergessen haben" und nicht etwa 123 oder gar 6 sein. Klar soweit?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    @Stollejay
    In deinem Listing gibt es kein if/then/else...
    (ich spreche vom letzten Listing von dir, wo ich dir geantwortet habe...)
    Hast du das schon per Hand durchgesteppt? Da wird jede If-Verzweigung angesprungen. (Da sollte dann mein Hinweis greifen!)
    Da kannst du doch feststellen, wie die Verzweigungen reagieren...
    Jetzt hat es "klick" gemach :D
    Ja klar... So funktioniert es:

    VB.NET-Quellcode

    1. ​Private Sub checkErrors()
    2. Dim millisPerDay As Integer = Integer.Parse(millisPerDay_tb.Text)
    3. Dim millisPerDay_error_text As String = ""
    4. Dim terrainToolMinRadius As Integer = Integer.Parse(terrainToolMinRadius_tb.Text)
    5. Dim terrainToolMaxRadius As Integer = Integer.Parse(terrainToolMaxRadius_tb.Text)
    6. Dim terrainToolMinRadius_error_text As String = ""
    7. Dim terrainToolMinStrength As Integer = Integer.Parse(terrainToolMinStrength_tb.Text)
    8. Dim terrainToolMaxStrength As Integer = Integer.Parse(terrainToolMaxStrength_tb.Text)
    9. Dim terrainToolMinStrength_error_text As String = ""
    10. If millisPerDay < 1000 Then
    11. checkError = False
    12. millisPerDay_error_text = millisPerDay_label_text(Lang) & " darf nicht weniger als 1000 sein!"
    13. End If
    14. If terrainToolMinRadius >= terrainToolMaxRadius Then
    15. checkError = False
    16. terrainToolMinRadius_error_text = "Min. Radius darf nicht größer oder gleich als Max. Radius sein!"
    17. End If
    18. If terrainToolMinRadius < 1 Then
    19. checkError = False
    20. terrainToolMinRadius_error_text = "Min. Radius darf nicht kleiner als 1 sein!"
    21. End If
    22. If terrainToolMinStrength >= terrainToolMaxStrength Then
    23. checkError = False
    24. terrainToolMinStrength_error_text = "Min. Stärke darf nicht größer oder gleich als Max. Stärke sein!"
    25. End If
    26. If terrainToolMinStrength < 1 Then
    27. checkError = False
    28. terrainToolMinStrength_error_text = "Min. Stärke darf nicht kleiner als 1 sein!"
    29. End If
    30. If checkError = False Then
    31. gridMain.IsEnabled = False
    32. gridMain_blur.Radius = 10
    33. gridError.Visibility = Visibility.Visible
    34. error_title.Content = "Error"
    35. error_text.Text = millisPerDay_error_text & vbNewLine & terrainToolMinRadius_error_text & vbNewLine & terrainToolMinStrength_error_text
    36. End If
    37. End Sub


    Natürlich muss ichs jetzt noch mal in "fein" machen denn das war erst mal nur zum Test. Danke euch :)
    Nur so am Rande - checkError gibt dir den Boolean schon vor:

    VB.NET-Quellcode

    1. gridMain.IsEnabled = checkError
    2. If Not checkError Then
    3. gridMain_blure.Radius =10
    4. gridError.Visibility=Visibility.Visible
    5. error_title.Context="Error"
    6. error_text.Text=....
    7. End If


    ...und mache dir in WPF einmal Gedanken über das mächtige Binding, dass dir dort bereitgestellt wird...

    lg VB1963

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

    Darf ich nochmal einwerfen, wie oben bereits angemerkt, dass die ganzen Abfragen mit einem NumericUpDown nicht notwendig wären, da dort in XAML definiert wird was Mindest- und Maximalwerte sind. Auch sind in einem NumericUpDown von vorneherein nichts anderes erlaubt als Zahlen.

    Leider hat MS vergessen das Control in WPF zu implementieren, aber es gibt mittlerweile das Extended Toolkit für WPF von Xceed.

    github.com/xceedsoftware/wpftoolkit

    zum Beispiel:

    XML-Quellcode

    1. <Window x:Class="Window1"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. mc:Ignorable="d"
    7. xmlns:wpfTool="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
    8. Title="Window1" Height="300" Width="300">
    9. <Grid>
    10. <wpfTool:DoubleUpDown ShowButtonSpinner="True" Minimum="0" Increment="0.1" Width="60" Height="20" TextAlignment="Right" HorizontalAlignment="Left"/>
    11. </Grid>
    12. </Window>


    Im Kit auch enthalten für Integer usw.