2010-02-13 14 views
13

Sto cercando di modificare il comportamento di un ComboBox di Windows.Forms in modo che il menu a discesa Completamento automatico visualizzi gli elementi in base alle regole specificate.Override Winform ComboBox Completamento automatico suggerimento Regola

Per impostazione predefinita, se si utilizza Completamento automatico in un ComboBox, la regola che viene seguita è "stringa s è inclusa nell'elenco a discesa se (s.StartsWith (userEnteredTextInTheComboBox))" Tutto ciò che mi interessa è sostituire un nuovo regola per quello attuale, ma non riesco a trovare alcun modo per arrivarci. (In particolare, preferirei s.Contains invece di s.StartsWith.)

posso kludge insieme una soluzione goffa utilizzando due comandi invece di uno, ma mi piacerebbe davvero essere più felice con quello che fa in realtà quello che voglio .

Aggiornamento: ho trovato essenzialmente the same question dopo qualche altra ricerca. La risposta fornita suggerisce che usare due controlli per "fingere" è la strada da seguire.

risposta

17

Ho avuto lo stesso problema e ho cercato una soluzione rapida.

Alla fine ho finito per scriverlo da solo. È un po 'sporco, ma non dovrebbe essere difficile renderlo più carino se necessario.

L'idea è di ricostruire l'elenco combinato dopo ogni pressione di un tasto. In questo modo si può contare su un'interfaccia integrata del combo, e non abbiamo bisogno di implementare la nostra interfaccia con una casella di testo e una casella di riepilogo ...

Basta ricordarsi di impostare combo.Tag a null se si ri-costruire il lista delle opzioni di combo.

private void combo_KeyPress(object sender, KeyPressEventArgs e) { 
    comboKeyPressed(); 
} 

private void combo_TextChanged(object sender, EventArgs e) { 
    if (combo.Text.Length == 0) comboKeyPressed(); 
} 

private void comboKeyPressed() { 
    combo.DroppedDown = true; 

    object[] originalList = (object[])combo.Tag; 
    if (originalList == null) { 
     // backup original list 
     originalList = new object[combo.Items.Count]; 
     combo.Items.CopyTo(originalList, 0); 
     combo.Tag = originalList; 
    } 

    // prepare list of matching items 
    string s = combo.Text.ToLower(); 
    IEnumerable<object> newList = originalList; 
    if (s.Length > 0) { 
     newList = originalList.Where(item => item.ToString().ToLower().Contains(s)); 
    } 

    // clear list (loop through it, otherwise the cursor would move to the beginning of the textbox...) 
    while (combo.Items.Count > 0) { 
     combo.Items.RemoveAt(0); 
    } 

    // re-set list 
    combo.Items.AddRange(newList.ToArray()); 
} 
+0

l'ho fatto, ma avrei dovuto spostare questa linea "combo.DroppedDown = true;" per essere l'ultima riga della funzione. Altrimenti genera un'eccezione quando si tenta di rimuovere l'ultimo elemento "combo.Items.RemoveAt (0);" – Ehsan

Problemi correlati