Search Ergebnis in separater Form mittels Event

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Spike.

    Search Ergebnis in separater Form mittels Event

    Hallo zusammen,

    ich stehe gerade etwas auf dem Schlauch, gerade weil ich das ganze schon einmal hatte, damalig hinbekommen habe und nun stehe ich wieder vor einer Denkblockade.
    Es gibt eine Datenbank mit verschiedenen spalten, eine Form mit einer Textbox sowie eine weitere Form wo die Suchergebnisse in einer DataGridView dargestellt werden.

    Nun möchte ich gerne bei Eingabe Event "TextChanged", dass ein separates Fenster unter der Textbox angezeigt wird mit dem gefilterten Ergebnis.
    Soweit funktioniert das auch, eine Form mit einer DataGridView und Datengebundender Tabelle wird dargestellt inkl. Einträge.
    Wenn ich nun Buchstaben in die Textbox der "Hauptform" eingebe, soll automatisch in der Form welche unterhalb der Textbox angezeigt wird, die DataGridView gefiltert werden.
    Das Ergebnis welches am nähsten liegt soll dann mittels Doppelklick ausgewählt werden können und die Textbox übernommen werden.

    Wieso ich dies nicht über den "AutoCompleteMode" mache, weil ich mehr als nur ein Ergebnis benötige in einer kompletten Darstellung statt nur ein Wort.
    Dies soll dem jenigen helfen auch das richtige ausgewählt zu haben von den verschiedenen vorschlägen.

    Derzeit habe ich das ganze mittels Timer gelöst, was aber wirklich nicht schön ist, seinen Dienst derzeit aber tut.
    Ich weiß das es anderweitig besser geht, komme aber leider selbst nicht mehr auf die Lösung.

    Hier einmal die "Hauptform" mit dem Textbox Event "TextChanged"...

    VB.NET-Quellcode

    1. Public Sub Buchungs_nameTextBox_TextChanged(sender As Object, e As EventArgs) Handles Buchungs_nameTextBox.TextChanged
    2. If Buchungs_nameTextBox.ReadOnly = False And openquicksearch = 0 Then
    3. With Buchungs_nameTextBox
    4. Dim r As Rectangle = New Rectangle(.Left, .Top, .Width, .Height)
    5. ' in Bildschirmkoordianten umrechnen
    6. r = Me.RectangleToScreen(r)
    7. ' Form unterhalb des Buttons platzieren
    8. Dim oForm As New frm_quicksearch_buchungsname
    9. oForm.StartPosition = FormStartPosition.Manual
    10. oForm.Location = New Point(r.Left + 5, r.Bottom + 10)
    11. 'Übergabe Kostenträger und Sachkonto an Load
    12. quicksearch_kostentraeger = Kostentraeger_ComboBox.Text
    13. quicksearch_sachkonto = Sachkonten_ComboBox.Text
    14. ' Form anzeigen
    15. openquicksearch = 1
    16. oForm.Show()
    17. 'Focus auf Mainform wird gesetzt!
    18. Haushaltsprogramm_Mainform.Focus()
    19. 'Timer Start for Search
    20. 'frm_quicksearch_firmen.Timer_QuickSearch.Start()
    21. End With
    22. End If
    23. End Sub


    Und hier einmal die Form, welche bei Eingabe von Buchstaben angezeigt wird, sowie die DataGridView welche dann gefiltert wird (derzeit mit Timer):

    VB.NET-Quellcode

    1. Private Sub Timer_Quicksearch_Tick(sender As Object, e As EventArgs) Handles Timer_Quicksearch.Tick
    2. Dim Kostentraeger = frm_buchungen.quicksearch_kostentraeger
    3. Dim Sachkonto = frm_buchungen.quicksearch_sachkonto
    4. If frm_buchungen.openquicksearch = 0 Then
    5. Me.Close()
    6. End If
    7. 'Bei Texteingabe wird nach vorhandenen Firmen gesucht!
    8. Dim FilterBuchungsName_QuickSearch As String = "*" & frm_buchungen.Buchungs_nameTextBox.Text
    9. 'Aktuell geladene Tabelle wird auf Firmennamen durchsucht!
    10. Me.V_buchungs_namenTableAdapter.Fill_DataGrid(Me.Finanz_managerDataSet.v_buchungs_namen, kostentraeger:=Kostentraeger, sachkonto:=Sachkonto)
    11. Me.V_buchungs_namenBindingSource.Filter = ("Convert(buchungs_name, 'System.String') LIKE '" & FilterBuchungsName_QuickSearch & "*'")
    12. V_buchungs_namenDataGridView.ClearSelection()
    13. End Sub
    14. Private Sub V_buchungs_namenDataGridView_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles V_buchungs_namenDataGridView.CellDoubleClick
    15. frm_buchungen.Buchungs_nameTextBox.Text = V_buchungs_namenDataGridView.CurrentCell.Value
    16. frm_buchungen.openquicksearch = 0
    17. Me.Close()
    18. End Sub


    Vielleicht hat jemand eine Idee oder einen Rat, vielen Dank!

    Greez Spike
    Und wozu brauchst Du jetzt den Timer? Da oForm ein SubForm von frm_buchungen ist, kann frm_buchungen direkt oForm manipulieren. Und wenn oForm dem frm_buchungen etwas mitteilen will, schickt es ein Event an frm_buchungen und frm_buchungen verarbeitet die gesendeten Daten. Dann kannst Du Dir sowas wie frm_buchungen.quicksearch_kostentraeger sparen. Sowas sollte man nicht machen. Der Zugriff auf Forms erfolgt mittels expliziten Instanzen oder Events, nicht mit der impliziten FormProperty.
    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.
    Hallo VaporiZed,

    Danke für deine Antwort!

    VaporiZed schrieb:

    Und wozu brauchst Du jetzt den Timer?

    Ohne Timer hatte ich es in der Tat versucht, leider hat sich bei der Eingabe von Buchstaben trotz des Events TextChanged nichts getan mit der Filterung des DataGridViews.
    Mit einem Timer hatte es dann funktioniert, was ich hierbei ebenfalls nicht ganz verstehe.

    Da ich inzwischen etwas ratlos bin was die Umstellung des Codes anbelangt, wie würdest du ihn hierbei umschreiben?
    Mein Vorgehen wäre: Nicht bei jedem TextChanged ein SubForm erstellen (das machst Du gerade, was sehr unperformant ist), sondern im Voraus eins erstellen und im TextChanged-EventHandler dieses ggf. anzeigen oder ausblenden. Und dann eben die Filtermethode dort direkt aufrufen. Also:

    VB.NET-Quellcode

    1. Public Sub Buchungs_nameTextBox_TextChanged(sender As Object, e As EventArgs) Handles Buchungs_nameTextBox.TextChanged
    2. If Buchungs_nameTextBox.ReadOnly OrElse openquicksearch <> 0 Then Return '*
    3. oForm.ApplyFilter() 'hier am besten noch die Werte übergeben, die Deine Filtermethode braucht.


    ApplyFilter ist der Ersatz für Deinen TimerTick-EventHandler.
    Statt also Deinen Timer laufen zu lassen und damit den TickEventHandler periodisch auszuführen, beinhaltet ApplyFilter die Codezeilen aus dem TimerTick-Event.

    * Der Unterschied zwischen And und AndAlso/Or und OrElse
    Anwendung einer If-Umkehrung, um die Übersicht zu verbessern bzw. die Codeverschachtelung zu verringern.
    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.
    Danke Dir, ist wirklich sehr Hilfreich und ich bin auch u.a. zu meinem gewünschten Ergebnis gekommen dadurch, funktioniert somit auch ohne Timer problemlos.

    Nun habe ich allerdings noch eine Sache..
    Ich übergebe u.a. auch die Eingabe, sprich das was in der Texbox steht an die nächste Form, was auch soweit ankommt.
    Leider wird in der DataGridView erst etwas dargestellt bzw. geladen wenn ich einen Buchstabe eingebe und diesen wieder mittels Return lösche.
    erst danach erhalte ich alle Einträge in der Liste. Wie schaffe ich es das diese vorgeladen wird bzw. auch u.a. schon die ersten 10 Inhalte darstellt?

    Hier der FormLoad und das nun erstellte ApplyFilter dazu:

    VB.NET-Quellcode

    1. Private Sub frm_quicksearch_buchungsname_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. Me.Opacity = 0
    3. Dim Kostentraeger = frm_buchungen.quicksearch_kostentraeger
    4. Dim Sachkonto = frm_buchungen.quicksearch_sachkonto
    5. 'Datagrids Buffer!
    6. DataGrids.SetDoubleBuffered(V_buchungs_namenDataGridView)
    7. Me.V_buchungs_namenTableAdapter.Fill_DataGrid(Me.Finanz_managerDataSet.v_buchungs_namen, kostentraeger:=Kostentraeger, sachkonto:=Sachkonto)
    8. Me.Opacity = 1
    9. End Sub


    VB.NET-Quellcode

    1. Public Sub ApplyFilter(Kostentraeger As String, Sachkonto As String, Eingabe As String)
    2. If frm_buchungen.openquicksearch = 0 Then
    3. Me.Close()
    4. End If
    5. Eingabe = "*" & Eingabe
    6. 'Aktuell geladene Tabelle wird auf Firmennamen durchsucht!
    7. Me.V_buchungs_namenTableAdapter.Fill_DataGrid(Me.Finanz_managerDataSet.v_buchungs_namen, kostentraeger:=Kostentraeger, sachkonto:=Sachkonto)
    8. Me.V_buchungs_namenBindingSource.Filter = ("Convert(buchungs_name, 'System.String') LIKE '" & Eingabe & "*'")
    9. V_buchungs_namenDataGridView.ClearSelection()
    10. End Sub


    Hättest du da eine Idee oder sehe ich da was falsch?

    VB.NET-Quellcode

    1. If frm_buchungen.openquicksearch = 0 Then
    :S
    Finger weg von solchen HauptFormZugriffen. Entweder du legst im HauptForm bereits fest, dass das SubForm in solch einem openquicksearch = 0-Fall geschlossen werden soll oder Du übergibst openquicksearch als Parameter.

    Spike schrieb:

    Leider wird in der DataGridView erst etwas dargestellt bzw. geladen wenn ich einen Buchstabe eingebe und diesen wieder mittels Return lösche.
    Wie kann man denn eine Eingabe in einer TextBox durch Drücken von Return löschen? Also, wie das geht, weiß ich natürlich, aber bei Deiner Formulierung weiß ich nicht, ob das so abläuft, wie ich mir das grad vorstelle. Wie sieht denn derzeit Dein TextBox-TextChanged-EventHandler von Anfang bis Ende aus?
    Bezüglich vorladen: Wann soll denn das SubForm angezeigt werden? Immer oder nur, wenn der TextBoxText geändert wurde? Kannst ja schreiben: Wenn TextBoxText leer ist (also keine Daten ans SubForm zum Filtern übergeben wurde), dann zeige wasauchimmer an, sonst eben das gefilterte Zeugsl.
    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.
    Danke auch für deinen ersten Hinweis, ist ebenfalls verbessert :)

    Fast-Vollzitat des direkten Vorposts an dieser Stelle entfernt ~VaporiZed

    Manches ist immer schwierig schriftlich zu erklären.
    Ich hatte in der Tat noch einen Fehler bei mir im Code, nun wird auch die DataGridView gefüllt und somit funktioniert alles, vielen Dank!

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