2010-02-13 27 views
13

Tôi đang cố sửa đổi hành vi của ComboBox của Windows.Forms để trình đơn thả xuống Tự động Hoàn tất hiển thị các mục theo các quy tắc tôi chỉ định.Ghi đè Winforms ComboBox Tự động hoàn tất Đề xuất Quy tắc

Theo mặc định, nếu bạn sử dụng AutoComplete trong ComboBox, quy tắc được theo sau là "chuỗi s được bao gồm trong trình đơn thả xuống nếu (s.StartsWith (userEnteredTextInTheComboBox))" Tất cả những gì tôi thực sự quan tâm là thay thế một quy tắc cho cái hiện tại, nhưng tôi không thể tìm ra cách nào để lấy nó. (Cụ thể, tôi thích s.Contains thay vì s.StartsWith.)

Tôi có thể kết hợp với nhau một giải pháp vụng về bằng cách sử dụng hai điều khiển thay vì một, nhưng tôi thực sự hạnh phúc hơn với điều thực sự làm những gì tôi muốn .

Cập nhật: Tôi tìm thấy về cơ bản the same question sau một số tìm kiếm khác. Câu trả lời được cung cấp ở đó cho thấy rằng việc sử dụng hai điều khiển để "giả mạo nó" là cách để đi.

Trả lời

17

Tôi đã gặp sự cố tương tự và tìm kiếm giải pháp nhanh.

Cuối cùng tôi đã tự viết nó. Đó là một chút bẩn nhưng nó không phải là khó khăn để làm cho nó đẹp hơn nếu cần thiết.

Ý tưởng là xây dựng lại danh sách kết hợp sau mỗi lần nhấn phím. Bằng cách này chúng ta có thể dựa vào giao diện tích hợp của combo, và chúng ta không cần phải thực hiện giao diện riêng của chúng ta với một hộp văn bản và một hộp danh sách ...

Chỉ cần nhớ đặt combo.Tag thành null nếu bạn xây dựng lại danh sách tùy chọn của 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

tôi đã làm nó nhưng tôi nên di chuyển dòng này "combo.DroppedDown = true;" để trở thành dòng cuối cùng của hàm. Nếu không, nó sẽ ném một ngoại lệ khi cố gắng loại bỏ mục cuối cùng "combo.Items.RemoveAt (0);" – Ehsan

Các vấn đề liên quan