none
MVVM - TextBox_TextChanged Event in ViewModel Klasse RRS feed

  • Frage

  • Hallo Zusammen,

    nun über

                            <TextBox Text="{Binding TextBarcodeScan}" TextChanged = "TextBox_TextChanged" MinHeight="20">
    

    erstelle ich in der xaml eine Textbox. Mit

    TextBarcodeScan

    binde ich den Inhalt an die ViewModel Klasse mit

            public string TextBarcodeScan
            {
                set
                {
                    if (textbarcodescan != value)
                    {
                        textbarcodescan = value;
                        OnPropertyChanged("TextBarcodeScan");
                    }
                }
                get { return textbarcodescan; }
            }
    

    Nun, wenn jetzt ein Eintrag über eine Tasttur ins Textfeld gemacht wird, dann wird nicht unmittelbar die Set-Routine von

    TextBarcodeScan

    angesprochen. Aus diesem Grund setze ich den

    TextChanged = "TextBox_TextChanged

    Event. Dieser wird aber in der Klasse MainWindow:Window definiert.

    Gibt es eine Möglichkeit dieses TextChanged Event auch im ViewModel abzugreifen?

    Vielen Dank für Eure Hilfe!

    Helau und Alaaf

    Gruß Martin


    Freitag, 1. März 2019 13:09

Antworten

  • Hi Martin,
    wozu benötigst Du das TextChanged-Ereignis?

    Im Setter der gebundenen Eigenschaft (TextBarCodeScan) bekommst Du die in der TextBox geänderte (erfasste) Zeichenkette. Mit <TextBox Text="{Binding TextBarcodeScan}" … wird die neue Zeichenkette erst zum Ende des Edit-Modus abgelegt; üblicherweise, wenn die TextBox den Focus verliert. Du kannst aber auch bei jedem "Tastenanschlag" die jeweils aktuelle Zeichenkette erhalten, wenn Du in der Bidung UpdateSourceTrigger setzt:

        <TextBox Text="{Binding TextBarcodeScan, UpdateSourceTrigger=PropertyChanged}" TextChanged = "TextBox_TextChanged" MinHeight="20"/>
    

    Wichtig in diesem Fall ist aber, dass die Verarbeitung im Setter nicht allzu lange dauert. Wenn das der Fall ist, dann kann die Oberfläche ausgebremst werden. Das sollte vermieden werden. Um das zu vermeiden, sollte man asynchrone Techniken einsetzen, z.B. werden die im Setter angekommenen Zeichenketten gepuffert und asynchron verarbeitet, in dem die folgende Zeichenkette, falls sie noch in der Phase der Verarbeitung kommt, einfach die Verarbeitung abbricht und neu startet, oder, indem nach der Verarbeitung einer Zeichenkette geschaut wird, ob weitere Zeichenketten gepuffert wurden und dann nur der letzte Puffereintrag verarbeitet wird.

    Oft reicht es auch aus, nur auf einem Zeichen in der Zeichenkette zu reagieren und dann asynchron die Verarbeitung zu starten.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort vorgeschlagen Peter Fleischer Samstag, 2. März 2019 05:34
    • Als Antwort markiert mApO18 Dienstag, 5. März 2019 08:50
    • Tag als Antwort aufgehoben mApO18 Mittwoch, 15. Mai 2019 06:18
    • Als Antwort markiert mApO18 Mittwoch, 12. Juni 2019 08:53
    Freitag, 1. März 2019 13:41

Alle Antworten

  • Hi Martin,
    wozu benötigst Du das TextChanged-Ereignis?

    Im Setter der gebundenen Eigenschaft (TextBarCodeScan) bekommst Du die in der TextBox geänderte (erfasste) Zeichenkette. Mit <TextBox Text="{Binding TextBarcodeScan}" … wird die neue Zeichenkette erst zum Ende des Edit-Modus abgelegt; üblicherweise, wenn die TextBox den Focus verliert. Du kannst aber auch bei jedem "Tastenanschlag" die jeweils aktuelle Zeichenkette erhalten, wenn Du in der Bidung UpdateSourceTrigger setzt:

        <TextBox Text="{Binding TextBarcodeScan, UpdateSourceTrigger=PropertyChanged}" TextChanged = "TextBox_TextChanged" MinHeight="20"/>
    

    Wichtig in diesem Fall ist aber, dass die Verarbeitung im Setter nicht allzu lange dauert. Wenn das der Fall ist, dann kann die Oberfläche ausgebremst werden. Das sollte vermieden werden. Um das zu vermeiden, sollte man asynchrone Techniken einsetzen, z.B. werden die im Setter angekommenen Zeichenketten gepuffert und asynchron verarbeitet, in dem die folgende Zeichenkette, falls sie noch in der Phase der Verarbeitung kommt, einfach die Verarbeitung abbricht und neu startet, oder, indem nach der Verarbeitung einer Zeichenkette geschaut wird, ob weitere Zeichenketten gepuffert wurden und dann nur der letzte Puffereintrag verarbeitet wird.

    Oft reicht es auch aus, nur auf einem Zeichen in der Zeichenkette zu reagieren und dann asynchron die Verarbeitung zu starten.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort vorgeschlagen Peter Fleischer Samstag, 2. März 2019 05:34
    • Als Antwort markiert mApO18 Dienstag, 5. März 2019 08:50
    • Tag als Antwort aufgehoben mApO18 Mittwoch, 15. Mai 2019 06:18
    • Als Antwort markiert mApO18 Mittwoch, 12. Juni 2019 08:53
    Freitag, 1. März 2019 13:41
  • Hallo Zusammen,

    danke Peter für deine Hilfe. Nun ich bin gerade dran, den Code auszulesen. Es funktioniert. Allerdings bin ich nocht nicht ganz zufrieden mit der Lösung und wollte mich nun der asychronen Technik nähern. Leider fehlt mir im Kopf der Zugang dafür. Aktuell habe ich folgende Lösung:

            // wird in der .XAML über UpdateSourceTrigger=PropertyChange nach jedem Tastendruck aktualisert
            public string TextBarcodeScan
            {
                set
                {
                    if (textbarcodescan != value)
                    {
                        textbarcodescan = value;
                        // TODO: sollte asynchron passieren, um Oberfläche nicht zu blockieren
                        OnPropertyChanged("TextBarcodeScan");
                        // Bedingung für Auswertung prüfen (Länge ausreichen?, ist Breite, Höhe und Type enthalten?
                        if (textbarcodescan.Length > 42 && textbarcodescan.IndexOf("§51'") != -1 && textbarcodescan.IndexOf("§09'") != -1 && textbarcodescan.IndexOf("§10'") != -1) TextBarcodeScanAuswerten();
                        if (textbarcodescan.Length > 35 && textbarcodescan.IndexOf("§09'") == -1)
                        {
                            IsPopupBarcodeScanVisible = false;
                            IsPopupPrüflingNichtVorhandenVisible = true;
                            PrüflingNichtVorhanden = "Folgender QR-Code wurde fehlerhaft eingelesen:\n " + textbarcodescan;
                        }
                    }
                }
                get { return textbarcodescan; }
            }

    Mit einem ersten Triggern vom Setter sollte ein asynchrone Routine ablaufen, die mir den String auswertet. Hier wäre irgendwie wichtig zu wissen, wann der Setter aufhört neue Zeichen zu erhalten um anschließen den String auszuwerten. Diesen Knoten im Kopf bekomme ich aktuell nicht raus ^^.

    Ich hoffe ihr könnt mir helfen.

    Vielen Dank.

    Liebe Grüße
    Martin

    Mittwoch, 15. Mai 2019 06:16