Sonderzeichen verbieten

  • Allgemein

Es gibt 189 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    Du kannst natürlich statt eines ToolTips auch einen nichtmodalen Dialog aufrufen und den entsprechend gestalten (BorderStyle None usw.), gugst Du hier.
    Du brauchst kein Attay c1, das kannst Du gleich so machen:

    VB.NET-Quellcode

    1. cc.AddRange(IO.Path.GetInvalidFileNameChars())
    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!
    Es genügt eine Zeile in KeyPress:

    Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    e.Handled = InStr("<>?: |\ /*" + Chr(34), e.KeyChar)
    End Sub

    Habe wegen der Lesbarkeit zwei Leerzeichen im String, vor | und /, die natürlich raus müssen!!!

    Jowat schrieb:

    Okay ich habe nun den Code so geändert:

    VB.NET-Quellcode

    1. Private cc As New List(Of Char)
    2. Dim c1() As Char = IO.Path.GetInvalidFileNameChars()
    3. Public Sub New()
    4. InitializeComponent()
    5. cc.AddRange(c1)
    6. End Sub
    7. Private Sub txtbox2_KeyDown(sender As Object, e As KeyEventArgs) Handles txtbox2.KeyDown
    8. If cc.Contains(Convert.ToChar(e.KeyValue)) Then
    9. e.SuppressKeyPress = True
    10. If txtbox2.Text.Contains(cc.ToString) Then MsgBox("Fehler")
    11. End If
    12. End Sub

    Weißt Du eigentlich, was Du da tust?

    Ich würde mal sagen, da fehlen einige wichtige Grundlagen.


    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles TextBox_ImportantText.KeyPress
    2. e.Handled = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar)
    3. End Sub

    Einfacher geht's nicht.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Ich verstehe den Code ein wenig aber nicht alles! Und irgendwie funktoniert das auch nicht denn SuppressKeyPress kein Member von System.Windows.Forms.KeyPressEventArgs.

    Deswegen habe ich das so gemacht:

    VB.NET-Quellcode

    1. Private IllegalChar As String = "<>?:|""\/*"
    2. Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
    3. If IllegalChar.Contains(e.KeyChar) Then
    4. e.Handled = True
    5. ToolTrip1.SetToolTip(TextBox1, "Fehler")
    6. End If
    7. End Sub


    Ich hoffe das es so auch einiger maßen richtig ist. Funktionieren tut es wunderbar und den Code verstehe ich zu 100%. Ist ja auch nichts schweres ran. Nur wird der ToolTrip nicht immer angezeigt. =/

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

    Das mit Tooltrip1 liegt daran das ich es bei mir ttip1 genannt habe und es hier auf die schnelle unbenannt habe damit mich keiner fragt was ttip1 ist. ^^
    Genau so heißt bei mir TextBox1: "txtbox2" und diverse andere Sachen wurden auch geändert. Aber nun gut. Kann man da nichts machen? Das ist echt nervig mit dem ToolTip. Manchmal wird's angezeigt, manchmal dann nicht...

    Und noch eine Frage. Bei den verbotenen Zeichen, das funktioniert zwar schön und gut. Aber bei Copy&Paste werden die dann wieder eingefügt. Gibt's da eine Lösung?
    @Jowat:
    Ok. Ich erklärs mal.
    (Vollständigkeitshalber hier nochmal der Code: )

    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles TextBox_ImportantText.KeyPress
    2. e.Handled = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar)
    3. End Sub


    Das KeyDown-Ereignis wird ausgelöst, sobald irgendeine Taste gedrückt wird.
    Das bedeutet, wenn Du Ctrl+V drückst, dann drückst Du wahrscheinlich zuerst die Ctrl-Taste (und hältst sie) und dann die V-Taste. Dabei wird das Event zuerst für Ctrl ausgeführt, dann nochmal für Ctrl+V.
    Ist ja logisch. Immer wenn eine Taste gedrückt wird, wird das Event ausgelöst.

    Dagegen das KeyPress-Ereignis:
    Es wird (vereinfacht ausgedrückt) immer dann ausgelöst, wenn der Tastendruck eine Veränderung am Text bewirkt.
    Also bei Ctrl+V wird das Event bei der Ctrl-Taste nicht ausgeführt. Erst, wenn Du die V-Taste drückst, wird das Event ausgelöst. Und dann steht in e.KeyChar auch nicht das V drin, sondern das Zeichen mit dem Code 22. (In der ASCII-Tabelle findest du an dieser stelle die Notation ^V. Öffne mal cmd und drücke Ctrl+V. Da kommt genau das daher.)

    Das bedeutet, dass Du KeyPress verwenden solltest, um Zeichen zu blockieren.




    Beim KeyPressEventArgs gibt's die Property "Handled".
    Setzt man diese auf True, wird das Zeichen nicht übernommen.
    Aber das hast Du bereits festgestellt.




    System.IO.Path.GetInvalidFileNameChars gibt ein Array mit ungültigen Zeichen zurück. Da nicht nur die von Dir erwähnten Zeichen "< > ? " : | \ / *" nicht erlaubt sind, sondern auch noch andere, lohnt es sich, diese ebenfalls zu filtern.
    Hier der Auszug aus ILSpy

    C-Quellcode

    1. // System.IO.Path
    2. private static readonly char[] InvalidFileNameChars = new char[]
    3. {
    4. '"',
    5. '<',
    6. '>',
    7. '|',
    8. '\0',
    9. '\u0001',
    10. '\u0002',
    11. '\u0003',
    12. '\u0004',
    13. '\u0005',
    14. '\u0006',
    15. '\a',
    16. '\b',
    17. '\t',
    18. '\n',
    19. '\v',
    20. '\f',
    21. '\r',
    22. '\u000e',
    23. '\u000f',
    24. '\u0010',
    25. '\u0011',
    26. '\u0012',
    27. '\u0013',
    28. '\u0014',
    29. '\u0015',
    30. '\u0016',
    31. '\u0017',
    32. '\u0018',
    33. '\u0019',
    34. '\u001a',
    35. '\u001b',
    36. '\u001c',
    37. '\u001d',
    38. '\u001e',
    39. '\u001f',
    40. ':',
    41. '*',
    42. '?',
    43. '\\',
    44. '/'
    45. };


    Wie Du siehst, ist da auch '\u0016' und '\b' drin.
    Das erste Zeichen ist hexadezimal angegeben. 0x16 ist 22. Und 22 ist, wie oben festgestellt, Ctrl+V.
    Das zweite Zeichen steht für Backspace. Also würde man keine Zeichen mehr löschen können.

    Diese Zeichen nennt man Control-Chars ("Steuerzeichen").
    Und um festzustellen, ob ein Zeichen ein Steuerzeichen ist, gibt's im .Net-Framework die Funktion Char.IsControl().




    Jetzt können wir alles zusammensetzen:
    Wann wollen wir das Zeichen blockieren? (Oder anders ausgedrückt: Wann wollen wir e.Handled auf True setzen?)
    -> Immer dann, wenn es in der Liste der ungültigen Zeichen drin ist.
    Aber: Wenn es ein Steuerzeichen ist, dann soll es trotzdem zugelassen werden.

    Mit System.IO.Path.GetInvalidFileNameChars bekommt man die ungültigen Zeichen. Mit .Contains() kann man prüfen, ob das angegebene Zeichen vorhanden ist.
    Also System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar).

    Und mit Char.IsControl(e.KeyChar) prüft man, ob das Zeichen ein Steuerzeichen ist.

    Wenn man jetzt noch gut nachdenkt, wie man die Bedingung zusammenstellen muss, hat man das:
    e.Handled = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar)

    Und das ist dann nur noch in die Sub reinzusetzen:

    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles TextBox_ImportantText.KeyPress
    2. e.Handled = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar)
    3. End Sub

    Wenn Du jetzt noch den ToolTip-Text ändern willst, ist nur eine kleine Änderung nötig:

    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles TextBox_ImportantText.KeyPress
    2. Dim Flag = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar)
    3. e.Handled = Flag
    4. If Flag Then
    5. ToolTrip1.SetToolTip(TextBox1, "Fehler")
    6. Else
    7. ToolTrip1.SetToolTip(TextBox1, "Alles OK") 'Nicht vergessen, den ToolTip auch wieder zu entfernen.
    8. End If
    9. End Sub
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Hi
    statt jedes mal System.IO.Path.GetInvalidFileNameChars abzufragen, kannst du auch einfach Static verwenden:

    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles TextBox_ImportantText.KeyPress
    2. Static invalidChars() As Char = System.IO.Path.GetInvalidFileNameChars
    3. e.Handled = Not Char.IsControl(e.KeyChar) AndAlso invalidChars.Contains(e.KeyChar)
    4. End Sub

    übrigens kann man per C&P dann immernoch ungültige Zeichen einfügen. D.h. du müsstest manuell auf die Nachrichten reagieren oder so.

    Gruß
    ~blaze~
    @~blaze~:
    Allgemein stimme ich Dir da zu.
    Da die Funktion so aussieht:

    C-Quellcode

    1. public static char[] GetInvalidFileNameChars()
    2. {
    3. return (char[])Path.InvalidFileNameChars.Clone();
    4. }

    hab ich mir gedacht, dass ein einfaches Kopieren des Arrays nicht allzuviel ausmacht.

    In diesem Fall gefällt mir aber die Verwendung von Static.
    Danke also.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Leute,

    Ich danke auch vielmals! Ich hab das verstanden und auch angewendet. Jedoch sind da 2 Fehler. (Derselbe Fehler-Typ)

    Ich hab jetzt den Code eingefügt:

    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles txtbox2.KeyPress
    2. Static InvalidChars() As Char = System.IO.Path.GetInvalidFileNameChars
    3. e.Handled = Not Char.IsControl(e.KeyChar) AndAlso InvalidChars.Contains(e.KeyChar)
    4. Dim Flag = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.Contains(e.KeyChar)
    5. e.Handled = Flag
    6. If Flag Then
    7. ttip1.SetToolTip(txtbox2, "Ungültiges Zeichen")
    8. Else
    9. ttip1.RemoveAll()
    10. End If
    11. End Sub


    Und hab das soweit auch verstanden und hoffe das es richtig ist. Nun steht aber das .Contains kein Member von System.Array heißt. Und System.Array hat auch keine ähnliche Funktion wie .Contains
    Was soll ich da jetzt tun?
    Jap ich benutze Visual Studio 2012 Ultimate unter Windows 8 x64 mit Net Framework 2. Und ich habe nun Contains(e.KeyChar) durch .IndexOf(Array, InvalidChars) <> -1
    Jedoch wird Array als Fehler deklariert! Da steht: "Array" ist ein Typ und kann nicht als Ausdruck verwendet werden. Was nun? :o
    Hey,

    Das dachte ich mir schon und hab es auch ausprobiert da kommt dann diese Fehlermeldung: Fehler bei der Überladungsauflösung, da keine zugreifbare "IndexOf" diese Anzahl von Argumenten akzeptiert.

    Code:

    VB.NET-Quellcode

    1. Private Sub CheckImportantKeyDown(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
    2. Static InvalidChars() As Char = System.IO.Path.GetInvalidFileNameChars
    3. e.Handled = Not Char.IsControl(e.KeyChar) AndAlso InvalidChars.IndexOf(InvalidChars) <> -1
    4. Dim Flag = Not Char.IsControl(e.KeyChar) AndAlso System.IO.Path.GetInvalidFileNameChars.IndexOf(InvalidChars) <> -1
    5. e.Handled = Flag
    6. If Flag Then
    7. ToolTip.SetToolTip(TextBox1, "Ungültiges Zeichen")
    8. Else
    9. ToolTip.RemoveAll()
    10. End If
    11. End Sub


    Desweiteren gibt es bei mir auch nicht den Befehl: TextBox1_ImportantText.KeyPress Deswegen habe ich es umbenannt in: TextBox1.KeyPress
    Ich hoffe das macht nichts aus.
    Ja, das mit dem IndexOf:
    Du erstellst ein Array, in InvalidChars()!
    Also musst du bei IndexOf eine Angabe im Parameter machen, also auf was sich das in InvalidChars bezieht.
    Denn so sind es zu viele Argumente.
    Mach das, indem du das Argument für die bestimmte Char hinter einem Komma im Parameter einsetzst.

    VB.NET-Quellcode

    1. InvalidChars.IndexOf(InvalidChars, DeineSpezielleChar) <> -1

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „programmer71“ ()

    Okay wenn ich das richtig verstanden habe soll ich es dann so machen? : (InvalidChars, "HIER VERBOETE ZEICHEN EINTARGEN")
    Ich dachte VB kennt die InvalidChars schon. Und wenn ich da zb. "1" eintrage, kann man es dennoch in die TextBox eintragen.