Willkommen bei dotnet-snippets.de! Snippet hinzufügen Login Registrieren
Snippets in der Datenbank: 1563 | Anzahl registrierter User: 1895 | Besucher online: 162
Hauptmenü
Home
Top Ten
Zufälliger Snippet
FAQs
.NET Community
dotnet-forum.de
dotnet-kicks.de
Social

RSS Feeds
Rss Alle Snippets
Rss C#
Rss VB.NET
Rss C++
Rss ASP.NET
Partner
Member of Microsoft Community Leader/Insider Program (CLIP)

Searchable ComboBox


Autor: Curry
Sprache: C#
Bewertung:
8.56 (2 votes)
Anzahl der Aufrufe: 3592
  
Kick it on dotnet-kicks.de  

Beschreibung:

Eine ComboBox, in der nach den enthaltenen Einträgen gesucht werden kann.
Es können keine neuen Einträge eingefügt werden und nur Begriffe eingegeben werden, die auch in der Liste enthalten sind.


Abgelegt unter: combobox, cb, searchable, suchen, suche.



C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Windows.Forms;

namespace MyUserControls
{
    /// <summary>
    /// ComboBox, die es ermöglicht, die darin enthaltenen
    /// Einträge zu suchen, jedoch keine neuen anzulegen.
    /// </summary>
    public class SearchableComboBox : ComboBox
    {
        /// <summary>
        /// Initialisiert eine durchsuchbare ComboBox.
        /// </summary>
        public SearchableComboBox()
        {
            // Autovervollständigung einschalten
            this.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            this.AutoCompleteSource = AutoCompleteSource.ListItems;

            // Einfügen von Text mittels Kontextmenüs verhindern
            this.ContextMenu = new ContextMenu();

            // Einzelne Tastendrücke abfangen
            this.KeyPress += new KeyPressEventHandler(SearchableComboBox_KeyPress);
        }

        /// <summary>
        /// Wird aufgerufen, wenn eine Taste gedrückt wird.
        /// Überprüft, ob es sich um eine gültige Taste handelt.
        /// </summary>
        private void SearchableComboBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            // Bei der Löschtaste die Methode verlassen
            if (e.KeyChar == '\b')
                return;

            string searchString = String.Concat(this.SelectedText != "" ? this.Text.Replace(this.SelectedText, "") : this.Text, 
                e.KeyChar.ToString());
            bool success = false;

            // Alle Einträge überprüfen, ob ein passender gefunden werden kann
            foreach (object item in this.Items)
            {
                if (item.ToString().StartsWith(searchString))
                {
                    success = true;
                    break;
                }
            }

            // Wenn es nicht erfolgreich war, den Tastendruck verhindern
            if (!success)
                e.Handled = true;
        }

        /// <summary>
        /// Verhindert das Einfügen von Text mithilfe von Strg + V.
        /// </summary>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Control | Keys.V))
                return true;
            else
                return base.ProcessCmdKey(ref msg, keyData);
        }
    }
}
Sie haben Fragen zu diesem Snippet oder brauchen Hilfe bei der .NET Entwicklung?
Freundliche und kompetente Entwickler helfen Ihnen gern weiter im Forum für .NET Entwicklung.



Kommentare:
(Zum Schreiben von Kommentaren bitte anmelden.)

Marcus schrieb am:  31.03.2011 09:35:08

Hi Curry,

ich habe das Snippet mal unter die Lupe genommen und konnte kleine Fehler finden.

1. Alle Buchstaben bist auf den ersten müssen doppelt eingegeben werden, damit sie angezeigt werden.
Die Prüfung hattest du bereits schon, doch kommt es bei dieser zu falschen Werten.

Ersetze
string searchString = String.Concat(this.SelectedText != "" ? this.Text.Replace(this.SelectedText, "") : this.Text, 
e.KeyChar.ToString());


mit
string searchString = string.Concat(this.SelectedText != string.Empty ? 
this.Text.Replace(this.SelectedText, string.Empty) : this.Text, e.KeyChar.ToString());


2. Wenn in die Combobox beispielsweise eigene Klassen aufgenommen werden, schlägt der Vergleich mit item.ToString() immer fehl, da diese nicht den eigentlichen Wert enthält.

Sobald also nun in this.DisplayMember ein Wert steht, sollte dieser auf vom Objekt abgerufen werden.

Somit sieht mein Schleifeninhalt wie folgt aus:
bool readFromProperty = this.DisplayMember != string.Empty;
string fieldText;

// Alle Einträge überprüfen, ob ein passender gefunden werden kann
foreach (object item in this.Items)
{
fieldText = item.ToString();

if (readFromProperty)
{
System.Reflection.PropertyInfo tmpInfo = item.GetType().GetProperty(this.DisplayMember);

if (tmpInfo != null)
{
fieldText = tmpInfo.GetValue(item, null).ToString();
}
}

if (fieldText.StartsWith(searchString))
{
success = true;
break;
}
}
Curry schrieb am:  31.03.2011 10:18:47

Hi,

danke dass du dir das Snippet angesehen hast.

Zu 1.: Du hast doch nicht anderes gemacht, als "" durch String.Empty auszutauschen? Und ich muss keinen Buchstaben doppelt eingeben.

2.: Ok, das stimmt sehr wohl :-)
Christopher Kk schrieb am:  31.03.2011 10:20:13

Mir ist gerade nicht ganz klar warum du so ein Aufwand betriebst? Für Comboboxes gibts doch AutoCompletion Sources und auch AutoCompletion-Modies mit denen man genau das von dir simulierte bereites umsetzen kann. Hat das einen bestimmten Grund?
Marcus schrieb am:  31.03.2011 11:00:20

@Curry
ja, ich habe nur "" zu string.Empty ersetzt. Dadurch hat es bei mir auch funktioniert.
Es ist generell besser string.Empty statt "" zu verwenden.

@Christopher
Genau das habe ich mir zuerst auch gedacht. Aber als ich gesehen hatte, dass er die
            // Autovervollständigung einschalten
this.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
this.AutoCompleteSource = AutoCompleteSource.ListItems;
setzt, musste ich mir den code genauer ansehen.

Ziel des Codes ist es, dass der Benutzer in der Combobox nur Texte eingeben kann, die in der Collection vorhanden sind.
Curry schrieb am:  31.03.2011 11:00:27

Ja, gibt es.
Ich benutze in diesem Fall ja auch AutoCompletion. Allerdings soll man keine Werte hineinschreiben können, die nicht existieren. Und dafür gibt es meines Wissens keine Bordmittel-Lösung.
Hab das Control in ein DataGridViewColumn integriert. Falls jemand daran intressiert ist, kann ich das ganze ja mal posten.
Christopher Kk schrieb am:  31.03.2011 11:41:22

Ahh alles klar verstehe es jetzt.
Aber wenn ich die Bordmittel nutze und was in der Box eingebe was es nicht gibt, dann wird mir doch auch nichts vorgeschlagen und dann sollte doch bei jedem halbwegs entwickelten Menschen im Kopf klar sein, dass es keine Elemente gibt mit dem Suchbegriff oder? :) Ansonsten sauberes Snippet, kriegst volle Punkte von mir.
Curry schrieb am:  31.03.2011 11:48:31

Danke :-)
Ja, aber bei mir in der Firma kann man sich bei den Usern nicht so ganz sicher sein, ob die über einen gesunden Menschenverstand verfügen ;P Man muss immer mit dem dümmsten User rechnen :-)


schlecht sehr gut
1 2 3 4 5 6 7 8 9 10
Nur angemeldete User können Snippets bewerten.