2010-02-13 9 views
13

Próbuję zmodyfikować zachowanie ComboBoxa Windows.Forms, aby lista rozwijana autouzupełniania wyświetlała elementy zgodnie z określonymi przeze mnie regułami.Zastąpienie WinForm ComboBox Autouzupełnianie Zasugeruj Zasada

Domyślnie, jeśli używasz autouzupełniania w ComboBox, reguła, która jest przestrzegana to "string s jest zawarty w rozwijanym menu, jeśli (s.StartsWith (userEnteredTextInTheComboBox))" Wszystko, co mnie naprawdę interesuje, to zastąpienie nowego rządzić obecnym, ale nie mogę znaleźć sposobu, aby się do niego dostać. (W szczególności wolałbym s.Contains zamiast s.StartsWith.)

Mogę kludować razem niezdarne rozwiązanie za pomocą dwóch kontrolek zamiast jednego, ale byłbym naprawdę bardziej zadowolony z tego, który faktycznie robi to, co chcę .

Aktualizacja: Znalazłem zasadniczo the same question po dalszych poszukiwaniach. Dostarczona tam odpowiedź sugeruje, że używanie dwóch kontrolek do "podrabiania" jest drogą do zrobienia.

Odpowiedz

17

Miałem ten sam problem i szukałem szybkiego rozwiązania.

Ostatecznie sam napisałem. Jest trochę brudny, ale w razie potrzeby nie powinno być trudno go uładzić.

Chodzi o to, aby po każdym naciśnięciu klawisza ponownie utworzyć listę kombinacji. W ten sposób możemy polegać na wbudowanym interfejsie combo i nie musimy implementować naszego własnego interfejsu z polem tekstowym i listbox ...

Pamiętaj tylko, aby ustawić combo.Tag na null, jeśli ponownie zbudujesz lista opcji 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

Zrobiłem to, ale muszę przejść ten wiersz „combo.DroppedDown = true;” aby być ostatnim wierszem funkcji. W przeciwnym razie zgłasza wyjątek podczas próby usunięcia ostatniego elementu "combo.Items.RemoveAt (0);" – Ehsan

Powiązane problemy