Textbox auswählen nach Datumsauswahl in DateTimePicker

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Textbox auswählen nach Datumsauswahl in DateTimePicker

    Moin moin
    Ich habe einen DateTimePicker und möchte, dass die TextBox "TBCustomer" nach der Auswahl eines Datums selektiert wird.
    Das habe ich nun im ValueCHanged Event des DTP gemacht. Funktioniert aber nicht. Die TB bekommt keinen Fokus, wenn ich ein Datum mit der Maus aus dem DTP auswähle - das Event wird aber gefeuert.
    Um dies zu testen, habe ich eine MessageBox im Code eingefügt, mit dieser klappt es. Nachdem ich auf OK klicke, hat meine TB den Fokus, ohne TB eben nicht.
    Was mache ich hier falsch?
    Ich habe auch das Leave Event des DTP versucht, aber bringt auch nix.

    VB.NET-Quellcode

    1. Private Sub DTPIncomeDate_ValueChanged(sender As Object, e As EventArgs) Handles DTPIncomeDate.ValueChanged
    2. GetIncome()
    3. 'Messagebox.show("d")
    4. TBCustomers.Select()
    5. End Sub


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub GetIncome()
    2. Dim IncomeDate As Date = Date.Parse(DTPIncomeDate.Value.ToString("dd.MM.yyyy"))
    3. 'Textboxen leeren
    4. For Each TB As Control In TBList
    5. TB.Text = ""
    6. Next
    7. TBCustomers.Text = ""
    8. LBLDailyIncome.Text = ""
    9. 'prüfen ob Datum bereits existiert und in Variable speichern
    10. Dim IncomeRow = DtsSettings.DailyIncome.FirstOrDefault(Function(x) x._Date.Date = IncomeDate)
    11. If IncomeRow Is Nothing Then Return
    12. TBCustomers.Text = IncomeRow.CustomerCount.ToString
    13. LBLDailyIncome.Text = (IncomeRow.DailyIncome / 100).ToString
    14. IncomeDate = IncomeRow._Date
    15. 'Schleife durch ListOf(TB), zum laden der Warengruppeneinnahmen
    16. For Each TB As Control In TBList
    17. Dim Groupname As String = TB.Name.Substring(3)
    18. Dim ProductGroupRow = DtsSettings.Distribution_Table.SingleOrDefault(Function(x) x.DailyIncomeRow._Date.Date = IncomeDate AndAlso x.ProductGroupRow.Name = Groupname)
    19. If ProductGroupRow Is Nothing Then Return
    20. TB.Text = (ProductGroupRow.ProductGroupIncome / 100).ToString
    21. Next
    22. End Sub
    @DerSmurf Wie wäre es mit TBCustomers.Focus()?
    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!
    @RodFromGermany
    .Focus() habe ich gerade ausprobiert. Das Verhalten ist exakt wie bei .Select()

    @ErfinderDesRades
    Eine Tabreihenfolge habe ich im Designer festgelegt. (TabIndex, TBCustomers hat den Index 0)
    Aber das bestimmt doch nur das Verhalten, wenn ich mit Tab durchschalte, oder meinst du etwas anderes?

    DerSmurf schrieb:

    .Focus() habe ich gerade ausprobiert.
    Bei mir funktioniert das wunderbar.
    Hast Du iwelchen krummen Code in einen Eventhandlern?
    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!
    Da .Focus() und .Select() wirkungsgleich sind, .Focus() jedoch vor/bei IntelliSense versteckt wird, ist das Kaninchen woanders verbuddelt.

    ##########

    @DerSmurf:
    Ich habe folgendes gefunden: Ich tippe darauf, dass das Schließen des angezeigten MonthCalendars nicht verzögerungsfrei ist. Wenn man bei der TextBox das GotFocus-Event abonniert, wird dieses erreicht. Abber offensichtlich wird der Fokus sofort wieder an den DTP zurückgegeben, weil der MonthCalendar noch am Schließen ist.
    Auf CodeProject fand ich den Hinweis für das entsprechende Event: CloseUp. Abonniere es zusätzlich und beide Datumsauswahlstandardoptionen (Direkteingabe, Datumsauswahl) führen zum Fokuswechsel:

    VB.NET-Quellcode

    1. Private Sub DTPIncomeDate_ValueChanged(sender As Object, e As EventArgs) Handles DTPIncomeDate.ValueChanged, DTPIncomeDate.CloseUp
    2. TBCustomers.Select()
    3. End Sub

    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.

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

    @VaporiZed
    du bist ein verdammter Traum. Vielen Dank!
    Ich habe das ganze jetzt wie folgt gelöst, damit die GetIncome Prozedur nur einmal läuft.
    Denn wenn ich schrittweise durchgehe und über den Month Calendar ein Datum auswähle, werden beide Events gefeuert.

    VB.NET-Quellcode

    1. Private Sub DTPIncomeDate_ValueChanged(sender As Object, e As EventArgs) Handles DTPIncomeDate.ValueChanged
    2. GetIncome()
    3. TBCustomers.Select()
    4. TBCustomers.SelectionStart = TBCustomers.Text.Length
    5. End Sub
    6. Private Sub DTPIncomeDate_CloseUp(sender As Object, e As EventArgs) Handles DTPIncomeDate.CloseUp
    7. TBCustomers.Select()
    8. TBCustomers.SelectionStart = TBCustomers.Text.Length
    9. End Sub



    DerSmurf schrieb:

    ? Was für ein Fehler?
    Dieser:

    DerSmurf schrieb:

    Funktioniert aber nicht.
    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!
    @RodFromGermany
    Bitte verzeih, aber ich verstehe nicht worauf du hinaus willst.

    @VaporiZed
    Bei der Verwendung des Programmes mit oben gepostetem Code, habe ich nun das nächste Problem (vielleicht hast du davon ja auch mal was gehört).
    Wenn ich nun im geöffneten Month Calendar etwas anklicke (also eine Jahreszahl z.B.) verschwindet der Kalender.
    Ich kann mich nicht bis zu einem Datum durchklicken.
    Aber ich werde nachher mal eine DemoApp erstellen.

    Edit:
    Habe die Ursache des Problem gefunden. Ich kann mir vorstellen, dass es schwer wird, hier eine Lösung zu finden.
    Das DTPChangeEvent wird bereits bei der ersten Auswahl gefeuert.
    Wenn ich also den Month Calendar auf die Jahresansicht umschalte und ein Jahr auswähle, ändert sich das Datum, das Change Event feuert, meine Textbox wird selektiert und der Calendar geschlossen.
    Also Beispielsweise möchte ich den 03.03.2011 auswählen, dann klicke ich auf den Header des Kalenders (da wo Mai2020 steht), solange bis ich die Jahreszahlen in 10 Jahresbereichen auswählen kann.
    Dann klicke ich auf 2010-2019 (ich will ja 2011) und das Datum ändert sich in den 23.Mai 2010 - damit bin ich ja noch nicht fertig mit meiner Datumsauswahl (03.03.2011 wollte ich ja).
    Aber das Change Event feuert, die Textbox wird ausgewählt und mein Kalender ist zu :(
    Die sinnbefreite DoubleUpTheLabelValue Sub, symbolisiert dabei die Sub GetIncome() aus dem Originalprogramm welche nur einmal laufen soll (wobei auch eine doppelte Ausführung nicht so das Problem wäre - Inhalt der Sub steht ja oben - aber muss ja nicht sein)

    Demoprojkekt im Anhang

    Das Einzige was mir einfällt ist nur das CloseUp Event zu verwenden. Dieses feuert ja erst, wenn sich der MonthCalendar schließt - wenn ich also mein Datum fertig ausgewählt habe.
    Natürlich habe ich dann kein Event mehr, wenn ich das Datum "von Hand" ändere, also aus der 23 (.Mai 2020) eine 25 mache.
    Aber da drücke ich dann halt einmal auf Tab.
    Also wäre nicht schlimm, wenn es für das Problem keine Lösung gibt (weils Problem ist ja hausgemacht).
    Aber vielleicht hat ja einer eine Idee.
    Dateien
    • DTPTest.zip

      (54,51 kB, 66 mal heruntergeladen, zuletzt: )

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

    Kurzer Einwurf: Warum arbeitest Du dann nicht stattdessen mit nem MonthCalendar und dessen DateSelected-Event(Handler)?

    ##########

    alternativ setzt Du ein Flag auf das Öffnen des DropDownCalendars und verhinderst so die Doppelabarbeitung des ValueChanged-EventHandlers:

    VB.NET-Quellcode

    1. Private ReactOnStandardValueChange As Boolean = True
    2. Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
    3. If Not ReactOnStandardValueChange Then ReactOnStandardValueChange = True : Return
    4. DoubleUpTheLabelValue()
    5. End Sub
    6. Private Sub DateTimePicker1_CloseUp(sender As Object, e As EventArgs) Handles DateTimePicker1.CloseUp
    7. DoubleUpTheLabelValue()
    8. End Sub
    9. Private Sub DateTimePicker1_DropDown(sender As Object, e As EventArgs) Handles DateTimePicker1.DropDown
    10. ReactOnStandardValueChange = False
    11. End Sub

    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.

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

    Huhu
    Das haut leider nicht hin, weil bei jedem Klick in den Calendar, der das Datum ändert (also Jahreszahlauswahl, Monatsauswahl), löst das CloseUp Event aus.
    Stünde hier TB.Focus() wäre mein Kalender ja wieder zu.

    VaporiZed schrieb:

    Kurzer Einwurf: Warum arbeitest Du dann nicht stattdessen mit nem MonthCalendar und dessen DateSelected-Event(Handler)?

    Ich brauche letzlich überwiegend eine Textbox mit Datum. Dann einen Button für ein Tag dazu und einen Button ein Tag weniger.
    Die Auswahl des Datums (also den Kalender) brauche ich sehr viel seltener.
    Deswegen erschien mir der DTP als richtiges Control - letztlich eine Textbox, die einen Kalender anzeigen kann - wenn ich ihn denn mal brauche.

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

    DerSmurf schrieb:

    Das haut leider nicht hin, weil bei jedem Klick in den Calendar, der das Datum ändert (also Jahreszahlauswahl, Monatsauswahl), löst das CloseUp Event aus.
    Nicht bei mir. Nur wenn man ein konkretes Datum selektiert, wird das CloseUp-Event gefeuert. Weder bei Jahres-/Monatswechsel (Auswahl im DropDownCalendar), noch wenn man das Datum ohne Kalender ändert/wählt.

    DerSmurf schrieb:

    Ich brauche letzlich überwiegend eine Textbox mit Datum. Dann einen Button für ein Tag dazu und einen Button ein Tag weniger.
    Dann änder doch die Property ShowUpDown auf True. Dann wird kein Kalender angezeigt, sondern ein Hoch-Runter-Spinfield (?)
    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.
    Ah mist. Passiert bei mir doch nicht.
    Ich habe mir einen Haltepunkt in die ValueChange Sub gesetzt. Ich denke mal dieses hat das Close Up Event dann ausgelöst.
    Wenn ich aber im DateTimePicker so weit zurück gehe wie möglich (also in die 10Jahresauswahl), dann ist das Ergebnis meiner Textbox 8.
    Also wird das Change Event insgesamt 3 mal ausgelöst - bzw. die Sub darin 3 mal ausgeführt.
    Mit deinem Code wird doch beim ersten Durchlauf des Change Events ReactOnStandardValueChange auf False gesetzt, aber dannach feuert das Event ja munter weiter, weil das DropDown Event nur einmal ausgelöst wird.
    Es müsste ja True bleiben, solange das DropDown visible ist.

    Edit: Ich bräuchte so etwas:

    VB.NET-Quellcode

    1. Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
    2. 'If Not ReactOnStandardValueChange Then ReactOnStandardValueChange = True : Return
    3. If Not DateTimePicker1.DropDown.visible Then
    4. DoubleUpTheLabelValue()
    5. TextBox1.Select()
    6. End If
    7. End Sub


    Den MonthCalendar schaue ich mir nachher mal in Ruhe an, ich kann mir vorstellen, dass das Control eventuell geeigneter ist, wenn ich den Kalender an sich verstecken kann.
    AUch wenn ich auf die schnelle keine ShowUpDown Property finde. (Aber wie gesagt, setz ich mich später in Ruhe mit auseinander)
    Ich brauche hier eins nach dem anderen :o)

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

    Du hast recht. So geht's:

    VB.NET-Quellcode

    1. Private TimeValueChangedWasFired As Integer = 0
    2. Private ReactOnStandardValueChange As Boolean = True
    3. Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
    4. If Not ReactOnStandardValueChange Then Return
    5. IncrementShownValue()
    6. End Sub
    7. Private Sub IncrementShownValue()
    8. TimeValueChangedWasFired += 1
    9. Label2.Text = TimeValueChangedWasFired.ToString
    10. End Sub
    11. Private Sub DateTimePicker1_CloseUp(sender As Object, e As EventArgs) Handles DateTimePicker1.CloseUp
    12. IncrementShownValue()
    13. ReactOnStandardValueChange = True
    14. End Sub
    15. Private Sub DateTimePicker1_DropDown(sender As Object, e As EventArgs) Handles DateTimePicker1.DropDown
    16. ReactOnStandardValueChange = False
    17. End Sub

    ShowUpDown ist ne Property vom DateTimePicker, nicht vom MonthCalendar.
    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.