Benutzer mit den meisten Antworten
AutoComplete - Nicht wirklich zufrieden...

Frage
-
Guten Abend,
ich bin heute auf die Idee gekommen, dass man nach einem Musiktitel suchen kann. Beispiel: Jemand kennt zwar den Titel, aber nicht den Interpreten. Jetzt möchte er zum Beispiel nach "Bilder im Kopf", ist von Sido.
Jetzt habe ich die AutoCompleteSource auf Custom gestellt, die Art auf SuggestAppend und die Autocomplete-Liste mit Interpreten und Titel gefüllt.
Fazit: Keine Treffer, weil, Sido steht vorne. Tippt man jetzt "si" ein, kommt zwar der Treffer, aber wenn man nicht weiß, von wem der Titel ist, ist das blöd.
Umgekehrt genauso doof. Ich könnte die Liste jetzt füllen mit zuerst dem Titel und dann dem Interpreten, aber was ist wenn jemand zwar den Namen eines Interpreten im Kopf hat, aber nicht den Titel?
So wirklich bin ich mit dem AutoComplete nicht zufrieden. Oder mache ich was falsch?
Frage: Ist es möglich das er auch Vorschläge macht wenn ich NUR "kopf" eingebe?
Und jetzt wo ich das so schreibe, fällt mir auf, dass ich AutoComplete ja irgendwie total falsch verstanden habe :-D Hach herrlich, bin ich doof :-D
Ich brauche ja was ganz anderes! Eine Suchfunktion die jedes mal sucht wenn sich am Text was ändert und Vorschläge macht. Okay, dass ist simpel. Aber wie mache ich das, dass unter der TextBox die Liste mit den Vorschlägen kommt?
Gruß
Andy
Antworten
-
Hallo, wenn alles in einem String "gespeichert" wird, dann brauchst du eine Art Volltextsuche.
Die normale TextBox unterstützt das so aber nicht. Nun weiß ich nicht ob du auch so ein Popup haben willst, wie es die TextBox macht oder ob sich vielleicht eine Standardmäßige Liste unter der TextBox besser für dich eignet.
Eine Liste fest unter der TextBox...
Füge dazu einfach eine ListBox bzw. eine ListView in deine Form ein. Im TextChanged-Event aktualisierst du dann deine Liste. Nachfolgend mal ein Beispiel über LINQ:Public Class Form1 Dim songs As New List(Of Song) Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged ListBox1.Items.Clear() ListBox1.Items.AddRange( _ songs.Where(Function(x) x.Artist.Contains(TextBox1.Text) Or x.Title.Contains(TextBox1.Text)) _ .Select(Function(x) x.Artist & " - " & x.Title) _ .ToArray()) End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 2"}) songs.Add(New Song() With {.Artist = "Interpret 2", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 1"}) End Sub End Class Class Song Public Property Title As String Public Property Artist As String End Class
Mit der Where-Methode überprüfe ich ob ein Song meinen Such-Kriterien entspricht. Dabei muss das Suchwort im Titel oder im Interpreten vorkommen. Es gibt aber noch bessere Möglichkeiten [1].
Mit Hilfe der Select-Methode erzeuge ich einen String, der dann ausgegeben wird.
Die ToArray-Methode formt dann ein Array, welches von AddRange aufgenommen werden kann.Solltest du die ListBox nun doch nicht permanent anzeigen wollen, dann kannst du dir eine neue Form erstellen und die ListBox dort hinein packen. Beim Fokuswechsel auf die TextBox öffnest du die Form dann nicht Modal (Show(Me)). Die Position musst du dann natürlich noch manuell setzen und beim bewegen der Hauptform die Unterform mit verschieben. Beim wechsel des markierten Elements kannst du dann über ein Event der Hauptform sagen was in der TextBox erscheinen soll. Diese Lösung ist sicherlich nicht die einfachste. Für VB.NET konnte ich leider keine wirklich empfehlkenswerte Lösung finden. Für C# gibts einiges, beispielsweise das hier.
[1] Besser wäre es wenn auch "Sido Bilder" einen Treffer landen würde. Dazu müsstest du das das Suchwort in die einzelnen Wörter aufspalten (.Split(" "c)) und dann jedes einzeln prüfen. Die Ergebnisse solltest du ab einer gewissen anzahl von getroffenen Wörtern auswählen.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.- Als Antwort markiert AndreasMahub Samstag, 30. November 2013 22:22
-
Verständlich ausgedrückt hast du es. Das Problem liegt nur, wie so oft, bei Windows. Die meisten .NET Windows Forms-Controls sind bloß so genannte Wrapper zu den nativen Windows-Controls. Diese kann man leider so gut wie nicht anpassen.
Ich habe trotzdem mal etwas herum probiert und dabei bin ich noch auf eine andere Idee gekommen. Um die ListBox kommst du zwar auch hier nicht herum, aber du sparst dir schonmal das Fenster, was vieles vereinfacht.
Als erstes habe ich die ListBox ausgeblendet (Visible = False). Wichtig bei dieser ist, das sie das vorderste Element ist. Außerdem muss die ListBox ein Teil der Form sein. Hier ist nun also mein Code:
Public Class Form1 Dim songs As New List(Of Song) Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged UpdateListBox() End Sub Private Sub UpdateListBox() If discardTextChanges Then Return 'Liste soll nicht aktualisiert werden' ListBox1.Items.Clear() If String.IsNullOrEmpty(TextBox1.Text) Then ListBox1.Items.AddRange(songs.Select(Function(x) x.Artist & " - " & x.Title).ToArray()) 'Alle Songs anzeigen' Else 'ListBox1.Items.AddRange( _ '' songs.Where(Function(x) x.Artist.Contains(TextBox1.Text) Or x.Title.Contains(TextBox1.Text)) _ '' .Select(Function(x) x.Artist & " - " & x.Title) _ '' .ToArray())' ListBox1.Items.AddRange( _ songs.Where(Function(x) (x.Artist & " - " & x.Title).ToLower().Contains(TextBox1.Text.ToLower())) _ .Select(Function(x) x.Artist & " - " & x.Title) _ .ToArray()) 'Hier kannst du dein eigenes Suchmuster anhand der Liste implementieren ''Oben meine Lösung aus meiner ersten Antwort, die darunter dient nur zum testen ''Durch ToLower wird die Groß/Kleinschreibung ignoriert' End If ListBox1.Visible = True UpdateListBoxPositionAndSize() 'Größe und Position der ListBox aktualisieren' End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'Testdaten hinzufügen' songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 2"}) songs.Add(New Song() With {.Artist = "Interpret 2", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 2"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 3"}) songs.Add(New Song() With {.Artist = "Interpret 4", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 4", .Title = "Titel 2"}) End Sub #Region "ListBox ein-/ausblenden" Private Sub TextBox1_Enter(sender As Object, e As EventArgs) Handles TextBox1.Enter ' ListBox1.Visible = True''Übernimmt UpdateListBox' UpdateListBox() 'Liste entsprechend aktualisieren' End Sub Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave If Not ListBox1.Focused Then ListBox1.Visible = False 'ListBox wieder ausblenden' End If End Sub #End Region ''' <summary> ''' Aktuelisiert die Position der ListBox ''' </summary> ' Sub UpdateListBoxPositionAndSize() Dim p = GetPosition(TextBox1) 'Position in relation zur Form ermitteln' ListBox1.Left = p.X ListBox1.Top = p.Y + TextBox1.Height ListBox1.Width = TextBox1.Width End Sub ''' <summary> ''' Ermittelt die Position eines Controls in Bezug zur Form ''' </summary> ' Function GetPosition(c As Control) As Point If c.Parent Is Nothing Then Return New Point(0, 0) 'Koordinaten der Form weg lassen' Else Dim p = GetPosition(c.Parent) Return New Point(c.Left + p.X, c.Top + p.Y) End If End Function Private Sub TextBox1_SizeChanged(sender As Object, e As EventArgs) Handles TextBox1.SizeChanged, TextBox1.Move UpdateListBoxPositionAndSize() End Sub Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown If e.KeyCode = Keys.Down Then 'In die ListBox springen um eine Steuerung mit der Tastatur zu zulassen' ListBox1.Focus() If ListBox1.Items.Count > 0 Then ListBox1.SelectedIndex = 0 'Mehr als 0 Elemente in der ListBox' End If End Sub Dim discardTextChanges As Boolean = False 'Aktualisieren der ListBox durch TextChange verhindern' Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged discardTextChanges = True If Not ListBox1.SelectedItem Is Nothing Then 'Es wurde ein Element ausgewählt' TextBox1.Text = ListBox1.SelectedItem.ToString() End If discardTextChanges = False End Sub Private Sub ListBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListBox1.KeyDown If e.KeyCode <> Keys.Down And e.KeyCode <> Keys.Up Then 'Hoch und Runter wird zum navigieren in der ListBox benötigt. ''Beim normalen Input allerdings springen wir wieder in die TextBox' UpdateListBox() 'Liste aktualisieren' TextBox1.Focus() 'TextBox fokusieren' TextBox1.SelectionLength = 0 'Cursor setzen' TextBox1.SelectionStart = TextBox1.Text.Length 'Die richtige Autovervollständigung würde hier alle tasten weiter leiten, die nicht Enter sind. ''Das brauchen wir hier aber nicht, da die ListBox alle möglichen Songs enthält.' If ListBox1.Visible = True And e.KeyCode = Keys.Enter Then ListBox1.Visible = False 'ListBox wird ausgeblendet, wenn die Entertaste gedrückt wurde' End If e.Handled = True End If End Sub Private Sub ListBox1_Leave(sender As Object, e As EventArgs) Handles ListBox1.Leave If Not TextBox1.Focused Then ListBox1.Visible = False End Sub Private Sub ListBox1_Click(sender As Object, e As EventArgs) Handles ListBox1.Click If Not ListBox1.SelectedItem Is Nothing Then 'Wurde ein Element ausgewählt?' TextBox1.Focus() 'TextBox fokusieren' TextBox1.SelectionLength = 0 'Cursor setzen' TextBox1.SelectionStart = TextBox1.Text.Length ListBox1.Visible = False 'Ausblenden, weil Auswahl mit Maus erfolgte' End If End Sub Private Sub TextBox1_Click(sender As Object, e As EventArgs) Handles TextBox1.Click 'Benutzer klickte erneut in die TextBox, also die Liste wieder anzeigen' ' ListBox1.Visible = True''Übernimmt UpdateListBox' UpdateListBox() End Sub End Class Class Song Public Property Title As String Public Property Artist As String End Class
Das Projekt samt Quellcode findest du auch noch einmal unter: http://sdrv.ms/1jVV06
(Rechtsklick > Herunter laden)In der Anwendung siehst ist wenige Pixel links der TextBox die Kante eines SplitContainers. Dadurch kannst du die Größe verändern. Die CheckBox und der Button haben keine Funktion. Durch einen klick auf diese wird aber der Fokus verschoben, wodurch die ListBox ausgeblendet wird.
PS: Wenn du auf ein Grafisch hochwertiges Programm, Freie anpassbarkeit und eventuell sogar Animationen abziehlst, dann ist WPF besser geeignet als Windows Forms. Ein Umstieg wird aber eventuell aufwendig und die Einarbeitungszeit in WPF ist auch nicht die Geringste. (Wenn man die neuen Features auch wirklich nutzen möchte.)
In der MSDN gibt es mehr dazu:
http://msdn.microsoft.com/de-de/library/ms754130.aspx
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.
- Bearbeitet Tom Lambert (Koopakiller)Moderator Sonntag, 1. Dezember 2013 00:47
- Als Antwort markiert AndreasMahub Sonntag, 1. Dezember 2013 09:31
Alle Antworten
-
Hallo, wenn alles in einem String "gespeichert" wird, dann brauchst du eine Art Volltextsuche.
Die normale TextBox unterstützt das so aber nicht. Nun weiß ich nicht ob du auch so ein Popup haben willst, wie es die TextBox macht oder ob sich vielleicht eine Standardmäßige Liste unter der TextBox besser für dich eignet.
Eine Liste fest unter der TextBox...
Füge dazu einfach eine ListBox bzw. eine ListView in deine Form ein. Im TextChanged-Event aktualisierst du dann deine Liste. Nachfolgend mal ein Beispiel über LINQ:Public Class Form1 Dim songs As New List(Of Song) Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged ListBox1.Items.Clear() ListBox1.Items.AddRange( _ songs.Where(Function(x) x.Artist.Contains(TextBox1.Text) Or x.Title.Contains(TextBox1.Text)) _ .Select(Function(x) x.Artist & " - " & x.Title) _ .ToArray()) End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 2"}) songs.Add(New Song() With {.Artist = "Interpret 2", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 1"}) End Sub End Class Class Song Public Property Title As String Public Property Artist As String End Class
Mit der Where-Methode überprüfe ich ob ein Song meinen Such-Kriterien entspricht. Dabei muss das Suchwort im Titel oder im Interpreten vorkommen. Es gibt aber noch bessere Möglichkeiten [1].
Mit Hilfe der Select-Methode erzeuge ich einen String, der dann ausgegeben wird.
Die ToArray-Methode formt dann ein Array, welches von AddRange aufgenommen werden kann.Solltest du die ListBox nun doch nicht permanent anzeigen wollen, dann kannst du dir eine neue Form erstellen und die ListBox dort hinein packen. Beim Fokuswechsel auf die TextBox öffnest du die Form dann nicht Modal (Show(Me)). Die Position musst du dann natürlich noch manuell setzen und beim bewegen der Hauptform die Unterform mit verschieben. Beim wechsel des markierten Elements kannst du dann über ein Event der Hauptform sagen was in der TextBox erscheinen soll. Diese Lösung ist sicherlich nicht die einfachste. Für VB.NET konnte ich leider keine wirklich empfehlkenswerte Lösung finden. Für C# gibts einiges, beispielsweise das hier.
[1] Besser wäre es wenn auch "Sido Bilder" einen Treffer landen würde. Dazu müsstest du das das Suchwort in die einzelnen Wörter aufspalten (.Split(" "c)) und dann jedes einzeln prüfen. Die Ergebnisse solltest du ab einer gewissen anzahl von getroffenen Wörtern auswählen.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.- Als Antwort markiert AndreasMahub Samstag, 30. November 2013 22:22
-
Hi Tom,
IM GRUNDE(!!!) schon mal geil was du dir da für mich ausgearbeitet hast.
Es gibt nur ein Problem: Die TextBox ist in einem Splitpanel. Und dieses Panel ist gerade mal so hoch, wie die TextBox selbst. Das ist kein Platz für eine Listbox. Ich möchte auch keine separate Listbox (höherer Programmieraufwand, siehe unten). Also Listbox weg!
Ich muss zum Zeitpunkt, wo dein Suchergebnis aufgelistet wird, direkt unter der TextBox die Listbox anzeigen lassen. Aber das ginge mit dem Panel nicht. Also fällt das weg.
Die EIGENTLICHE (von .NET mitgelieferte) AutoComplete-Funktion von der TextBox kann direkt unter der TextBox (auch mit dem Panel) eine Liste anzeigen (bzw. zeichnen).
Und genau so etwas möchte ich gerne, nur mit einem Unterschied: Ich möchte "die Macht haben" über die "Suchfunktion" haben.
Kann man vielleicht (ist nur so eine Idee!!!) mit einer eigener Klasse, welche über Inherits, die AutoComplete überladen das "verbessern"???
Man, wie soll ich das bloss erklären?! :-(
Also, die TextBox bietet ja AutoComplete an. Sie macht selbst schon tolle Sachen. Die TextBox selbst macht ja schon tolle AutoComplete (inkl. Zeichnen) Funktionen, die möchte ich auch nicht wegreden. ICH bin aber mit den "Suchergebnissen" nicht zufrieden, und würde gerne eine eigene (nennen wir sie mal) "SuchEngine" anbieten und das Ergebnis wiederum an die AutoComplete-Funktion übergeben.
Also ICH möchte mit MEINER Art suchen lassen. Nicht die AutoComplete-Funktion. Aber die AutoComplete darf gerne MEINE Ergebnisse anzeigen lassen.
Hab ich das so halbwegs verständlich ausgedrückt? :-)
Also ich finde das Thema spannend mit dem Überladen :-)
Liebe Grüße
Andy -
Verständlich ausgedrückt hast du es. Das Problem liegt nur, wie so oft, bei Windows. Die meisten .NET Windows Forms-Controls sind bloß so genannte Wrapper zu den nativen Windows-Controls. Diese kann man leider so gut wie nicht anpassen.
Ich habe trotzdem mal etwas herum probiert und dabei bin ich noch auf eine andere Idee gekommen. Um die ListBox kommst du zwar auch hier nicht herum, aber du sparst dir schonmal das Fenster, was vieles vereinfacht.
Als erstes habe ich die ListBox ausgeblendet (Visible = False). Wichtig bei dieser ist, das sie das vorderste Element ist. Außerdem muss die ListBox ein Teil der Form sein. Hier ist nun also mein Code:
Public Class Form1 Dim songs As New List(Of Song) Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged UpdateListBox() End Sub Private Sub UpdateListBox() If discardTextChanges Then Return 'Liste soll nicht aktualisiert werden' ListBox1.Items.Clear() If String.IsNullOrEmpty(TextBox1.Text) Then ListBox1.Items.AddRange(songs.Select(Function(x) x.Artist & " - " & x.Title).ToArray()) 'Alle Songs anzeigen' Else 'ListBox1.Items.AddRange( _ '' songs.Where(Function(x) x.Artist.Contains(TextBox1.Text) Or x.Title.Contains(TextBox1.Text)) _ '' .Select(Function(x) x.Artist & " - " & x.Title) _ '' .ToArray())' ListBox1.Items.AddRange( _ songs.Where(Function(x) (x.Artist & " - " & x.Title).ToLower().Contains(TextBox1.Text.ToLower())) _ .Select(Function(x) x.Artist & " - " & x.Title) _ .ToArray()) 'Hier kannst du dein eigenes Suchmuster anhand der Liste implementieren ''Oben meine Lösung aus meiner ersten Antwort, die darunter dient nur zum testen ''Durch ToLower wird die Groß/Kleinschreibung ignoriert' End If ListBox1.Visible = True UpdateListBoxPositionAndSize() 'Größe und Position der ListBox aktualisieren' End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'Testdaten hinzufügen' songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 1", .Title = "Titel 2"}) songs.Add(New Song() With {.Artist = "Interpret 2", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 2"}) songs.Add(New Song() With {.Artist = "Interpret 3", .Title = "Titel 3"}) songs.Add(New Song() With {.Artist = "Interpret 4", .Title = "Titel 1"}) songs.Add(New Song() With {.Artist = "Interpret 4", .Title = "Titel 2"}) End Sub #Region "ListBox ein-/ausblenden" Private Sub TextBox1_Enter(sender As Object, e As EventArgs) Handles TextBox1.Enter ' ListBox1.Visible = True''Übernimmt UpdateListBox' UpdateListBox() 'Liste entsprechend aktualisieren' End Sub Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave If Not ListBox1.Focused Then ListBox1.Visible = False 'ListBox wieder ausblenden' End If End Sub #End Region ''' <summary> ''' Aktuelisiert die Position der ListBox ''' </summary> ' Sub UpdateListBoxPositionAndSize() Dim p = GetPosition(TextBox1) 'Position in relation zur Form ermitteln' ListBox1.Left = p.X ListBox1.Top = p.Y + TextBox1.Height ListBox1.Width = TextBox1.Width End Sub ''' <summary> ''' Ermittelt die Position eines Controls in Bezug zur Form ''' </summary> ' Function GetPosition(c As Control) As Point If c.Parent Is Nothing Then Return New Point(0, 0) 'Koordinaten der Form weg lassen' Else Dim p = GetPosition(c.Parent) Return New Point(c.Left + p.X, c.Top + p.Y) End If End Function Private Sub TextBox1_SizeChanged(sender As Object, e As EventArgs) Handles TextBox1.SizeChanged, TextBox1.Move UpdateListBoxPositionAndSize() End Sub Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown If e.KeyCode = Keys.Down Then 'In die ListBox springen um eine Steuerung mit der Tastatur zu zulassen' ListBox1.Focus() If ListBox1.Items.Count > 0 Then ListBox1.SelectedIndex = 0 'Mehr als 0 Elemente in der ListBox' End If End Sub Dim discardTextChanges As Boolean = False 'Aktualisieren der ListBox durch TextChange verhindern' Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged discardTextChanges = True If Not ListBox1.SelectedItem Is Nothing Then 'Es wurde ein Element ausgewählt' TextBox1.Text = ListBox1.SelectedItem.ToString() End If discardTextChanges = False End Sub Private Sub ListBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListBox1.KeyDown If e.KeyCode <> Keys.Down And e.KeyCode <> Keys.Up Then 'Hoch und Runter wird zum navigieren in der ListBox benötigt. ''Beim normalen Input allerdings springen wir wieder in die TextBox' UpdateListBox() 'Liste aktualisieren' TextBox1.Focus() 'TextBox fokusieren' TextBox1.SelectionLength = 0 'Cursor setzen' TextBox1.SelectionStart = TextBox1.Text.Length 'Die richtige Autovervollständigung würde hier alle tasten weiter leiten, die nicht Enter sind. ''Das brauchen wir hier aber nicht, da die ListBox alle möglichen Songs enthält.' If ListBox1.Visible = True And e.KeyCode = Keys.Enter Then ListBox1.Visible = False 'ListBox wird ausgeblendet, wenn die Entertaste gedrückt wurde' End If e.Handled = True End If End Sub Private Sub ListBox1_Leave(sender As Object, e As EventArgs) Handles ListBox1.Leave If Not TextBox1.Focused Then ListBox1.Visible = False End Sub Private Sub ListBox1_Click(sender As Object, e As EventArgs) Handles ListBox1.Click If Not ListBox1.SelectedItem Is Nothing Then 'Wurde ein Element ausgewählt?' TextBox1.Focus() 'TextBox fokusieren' TextBox1.SelectionLength = 0 'Cursor setzen' TextBox1.SelectionStart = TextBox1.Text.Length ListBox1.Visible = False 'Ausblenden, weil Auswahl mit Maus erfolgte' End If End Sub Private Sub TextBox1_Click(sender As Object, e As EventArgs) Handles TextBox1.Click 'Benutzer klickte erneut in die TextBox, also die Liste wieder anzeigen' ' ListBox1.Visible = True''Übernimmt UpdateListBox' UpdateListBox() End Sub End Class Class Song Public Property Title As String Public Property Artist As String End Class
Das Projekt samt Quellcode findest du auch noch einmal unter: http://sdrv.ms/1jVV06
(Rechtsklick > Herunter laden)In der Anwendung siehst ist wenige Pixel links der TextBox die Kante eines SplitContainers. Dadurch kannst du die Größe verändern. Die CheckBox und der Button haben keine Funktion. Durch einen klick auf diese wird aber der Fokus verschoben, wodurch die ListBox ausgeblendet wird.
PS: Wenn du auf ein Grafisch hochwertiges Programm, Freie anpassbarkeit und eventuell sogar Animationen abziehlst, dann ist WPF besser geeignet als Windows Forms. Ein Umstieg wird aber eventuell aufwendig und die Einarbeitungszeit in WPF ist auch nicht die Geringste. (Wenn man die neuen Features auch wirklich nutzen möchte.)
In der MSDN gibt es mehr dazu:
http://msdn.microsoft.com/de-de/library/ms754130.aspx
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.
- Bearbeitet Tom Lambert (Koopakiller)Moderator Sonntag, 1. Dezember 2013 00:47
- Als Antwort markiert AndreasMahub Sonntag, 1. Dezember 2013 09:31
-
Hi Tom,
Sorry, bin leider etwas eingepennt :-D
PERFEKT!!!!!!!!!!!!!!!!!!! DANKE!!!!!!!!!!!!!!!
Allerdings legt sich die Listbox nicht "über" das Panel, sondern ist abgeschnitten. Ich habe einen Splicontainer, Ausrichtung ist Horizontal. Panel1 (oben) ist so hoch wie die TextBox. Die Listbox ist so gut wie nicht zu sehen, weil, das soll ja auch so sein. Aber man kann doch bestimmt die Listbox "zwingen" trotzdem als oberstes Control dargestellt zu werden.
Ansonsten: Danke, genau so wollte ich es! :-)
Liebe Grüße
Andy -
Ach ja, Nachtrag bzgl. WPF:
WPF ist wirklich eine ganz tolle Sache, ich habe mir auch dafür bereits 2 Bücher gekauft. Aber wenn ich ehrlich sein soll, ich glaube mit 40 Jahren jetzt noch so krass "umzudenken" fällt mir ehrlich gesagt echt schwer :-(
Würde ich sehr gerne können, aber das ist schon ein extremer Umstieg von Windows Forms auf WPF.
Gruß
Andy -
Also ich habe die ListBox nach ganz oben bekommen indem ich sie als letztes in die Form eingefügt habe.
Gucke mal in die Form.Designer.vb. Dort fiondest du eine Methode InitialisizeComponent, diese ist für das Aufbauen der GUI verantwortlich. Kurz vor dem Ede werden die Controls hinzugefügt. In meinem Beispiel sieht das so aus:
Me.Controls.Add(Me.ListBox1)
Me.Controls.Add(Me.CheckBox1)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.SplitContainer1)Die erste Zeile dieser Add-Befehle muss die ListBox hinzufügen. Dadurch legt diese sich über alle anderen Controls.
PS: Eventuell lohnt es sich, die ListBox auch breiter zu gestalten als die TextBox, das musst du aber anhand des Designs entscheiden.
Zu WPF, wenn du mal etwas Zeit übrig hast, solltest du es probieren. Vielleicht fällt es dir auch leichter, als du denkst ;)
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke. -
Solange die ListBox nicht größer ist als das Panel funktioniert das natürlich auch.
Wenn meine Lösung nicht richtig funktioniert, dann kann ich leider aus der Ferne auch nichts weiter dazu sagen. Entweder benutzt du ein Control das sich anders als erwartet verhält oder irgendwo in der Reihenfolge ist doch noch ein Fehler.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke. -
Solange die ListBox nicht größer ist als das Panel funktioniert das natürlich auch.
Wenn meine Lösung nicht richtig funktioniert, dann kann ich leider aus der Ferne auch nichts weiter dazu sagen. Entweder benutzt du ein Control das sich anders als erwartet verhält oder irgendwo in der Reihenfolge ist doch noch ein Fehler.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.Nein nein nein, dein Code funktioniert einwandfrei ;-)
Aber das Panel ist nur so hoch, wie die TextBox selbst und dadurch wird die Listbox drunter dann nicht mehr richtig dargestellt ;-) Daher habe ich es lediglich nur so abändern müssen, dass die Listbox im 2. (unteren) Panel ganz oben angezeigt wird ;-)
Danke nochmal ;-)
Gruß
Andy