2010-02-13 64 views
13

我試圖修改Windows.Forms組合框的行爲,以便自動完成下拉菜單根據我指定的規則顯示項目。覆蓋Winforms組合框自動完成建議規則

默認情況下,如果您在ComboBox中使用自動完成,則遵循的規則是「字符串s包含在下拉列表中,如果(s.StartsWith(userEnteredTextInTheComboBox))」我真正感興趣的是用新的規則爲目前的,但我無法找到它。 (具體來說,我更喜歡s.Contains,而不是s.StartsWith。)

我可以拼湊一個笨拙的解決方案,使用兩個控件而不是一個,但我真的會更開心一個實際上做我想做的事。

更新:經過一些更多的搜索後,我發現本質上the same question。在那裏提供的答案表明,使用兩個控件來「僞造」是要走的路。

回答

17

我有同樣的問題,並尋找一個快速解決方案。

最終我最終自己寫了。這有點骯髒,但如果需要,它不應該很難變得更漂亮。

這個想法是在每次按鍵後重新構建組合列表。這樣我們就可以依靠組合的內置界面上,我們並不需要自己實現一個文本框和列表框界面...

只記得設置combo.Tagnull如果你重新編譯組合的選項列表。

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

我做到了,但我應該搬到這條線「combo.DroppedDown = TRUE;」以成爲該功能的最後一行。否則,當試圖刪除最後一個項目「combo.Items.RemoveAt(0);」時會引發異常 – Ehsan 2017-02-28 13:07:25