2013-01-23 16 views
7

Đây là một chương trình ngắn tái tạo lại vấn đề tôi vừa gặp phải. Điều này đã được biên dịch theo MS Windows 7 với .NET 4.0, chỉ trong trường hợp tạo sự khác biệt.ComboBox SelectionChangeCommitted event không hoạt động với AutoComplete

using System; 
using System.Drawing; 
using System.Windows.Forms; 

// Compile with "csc /target:exe /out:comboboxbug.exe /r:System.dll /r:System.Drawing.dll /r:System.Windows.Forms.dll comboboxbug.cs" 
// in a Visual Studio command prompt. 

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     //Create a label. 
     Label oLabel = new Label(); 
     oLabel.Location = new Point (10, 10); 
     oLabel.Size = new Size (100, 15); 
     oLabel.Text = "Combo box bug:"; 

     // Create a combo-box. 
     ComboBox oComboBox = new ComboBox(); 
     oComboBox.Location = new Point (10, 50); 
     oComboBox.Size = new Size (150, 21); 
     oComboBox.Items.AddRange (new object[] 
      { "A", "A B", "A C", "A B C", "A C B", "A B C D", "A C B D" }); 
     oComboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend; 
     oComboBox.AutoCompleteSource = AutoCompleteSource.ListItems; 
     oComboBox.SelectionChangeCommitted 
      += new EventHandler (comboBox_SelectionChangeCommitted); 

     // Create a form. 
     Form oForm = new Form(); 
     oForm.Size = new Size (200, 150); 
     oForm.Controls.Add (oLabel); 
     oForm.Controls.Add (oComboBox); 

     // Run this form. 
     Application.Run (oForm); 
    } 
    static void comboBox_SelectionChangeCommitted (object sender, 
     EventArgs e) 
    { 
     MessageBox.Show ("SelectionChangeCommitted"); 
    } 
} 

Nhấp vào phần văn bản của hộp tổ hợp và nhập "A". Bạn sẽ nhận được danh sách các đề xuất tự động điền. Nhấp vào một trong các lựa chọn bằng chuột của bạn. Sự kiện SelectionChangeCommitted không xảy ra!

Chọn mục menu mà không sử dụng tự động hoàn thành. Bạn sẽ nhận được một hộp thông báo cho biết sự kiện SelectionChangeCommitted đã xảy ra!

Do lựa chọn đã được người dùng thay đổi trong cả hai trường hợp, không nên SelectionChangeCommitted được gọi trong cả hai trường hợp?

Sử dụng sự kiện SelectedIndexChanged không phải là một tùy chọn, bởi vì đối với ứng dụng đằng sau ví dụ đóng hộp này, tôi chỉ muốn nó xảy ra khi người dùng thực hiện lựa chọn chứ không phải khi được đặt theo chương trình.

+0

Tôi đã thử mã của bạn nhưng mọi thứ đều ổn. – spajce

+0

Bất kỳ cơ hội nào [vấn đề này] (http://stackoverflow.com/questions/13291945/winforms-combobox-loses-autocomplete-value-on-lostfocus) có giúp ích gì không? – Guvante

+0

@spajce: Tôi đã chạy mã nguồn ví dụ như được viết và sao chép hành vi được mô tả. Win 8, VS 2010, .NET 4 Hồ sơ khách hàng. Lưu ý rằng hành vi mong đợi là một cửa sổ bật lên khi chọn giá trị như một phần của quá trình tự động hoàn tất. – Guvante

Trả lời

2

Sử dụng sự kiện SelectedIndexChanged không phải là một tùy chọn, vì ứng dụng đằng sau ví dụ đóng hộp này, tôi chỉ muốn nó xảy ra khi người dùng thực hiện lựa chọn chứ không phải khi được đặt theo chương trình.

Bạn cũng có thể thực hiện việc này bằng cách viết phương pháp bao bọc để thay đổi lựa chọn tạm thời vô hiệu hóa sự kiện của bạn.

Thật không may, tôi không biết giải pháp cho vấn đề SelectionChangeCommitted không được bắt đầu cho trường hợp chung hơn (chẳng hạn như nơi bạn không kiểm soát ComboBox hoặc cách truy cập).

EDIT:

tôi đã thực hiện một streamer của tất cả các sự kiện mà ComboBox cuộc gọi, và nó không xuất hiện rằng bất kỳ sự kiện khác sẽ làm những gì bạn đang tìm kiếm. Giải pháp duy nhất tôi có thể nghĩ đến sẽ liên quan đến việc tìm kiếm các sự kiện mà AutoComplete kích hoạt. Khó khăn là biết những sự kiện đó là gì, vì chúng không xuất hiện để kích hoạt các ComboBox từ những gì thử nghiệm nhỏ của tôi cho thấy.

1

FYI, đây là giải pháp tốt nhất mà tôi từng đưa ra. Rõ ràng, đây là một xử lý sự kiện để lại trên một lớp con ComboBox. Sự kiện SelectionChangeCommitted không xảy ra khi nhấp chuột, nhưng ít nhất nó xảy ra trong luồng tương tác thông thường của giao diện GUI.

private void this_Leave (object sender, EventArgs e) 
{ 
    // If this is an autocomplete combo-box, select the 
    // item that was found by autocomplete. 
    // This seems like something that ComboBox should be 
    // doing automatically...I wonder why it doesn't? 
    if (this.AutoCompleteMode != AutoCompleteMode.None) 
    { 
     // Determine which combo-box item matches the text. 
     // Since IndexOf() is case-sensitive, do our own 
     // search. 
     int iIndex = -1; 
     string strText = this.Text; 
     ComboBox.ObjectCollection lstItems = this.Items; 
     int iCount = lstItems.Count; 
     for (int i = 0; i < iCount; ++i) 
     { 
      string strItem = lstItems[i].ToString(); 
      if (string.Compare (strText, strItem, true) == 0) 
      { 
       iIndex = i; 
       break; 
      } 
     } 

     // If there's a match, and this isn't already the 
     // selected item, make it the selected item. 
     // 
     // Force a selection-change-committed event, since 
     // the autocomplete was driven by the user. 
     if (iIndex >= 0 
     && this.SelectedIndex != iIndex) 
     { 
      this.SelectedIndex = iIndex; 
      OnSelectionChangeCommitted (EventArgs.Empty); 
     } 
    } 
} 
0

Nếu ai đó có vấn đề này, tôi đề nghị một giải pháp mà hoạt động tốt với tôi ...

suy nghĩ với tôi, để chấp nhận các đề nghị của Combo hộp, nói chung là người sử dụng cần để chìa khóa xuống với một phím Enter.

Bạn có thể viết vào KeyDown trường hợp sở hữu Combo hộp, một cái gì đó như thế này:

private void cboProperty_SelectionChangeCommitted(object sender, EventArgs e) 
    { 
     //Call here the event of SelectionChangeCommitted 
     cboProperty_SelectionChangeCommitted(sender,null); 
    } 

Nó sẽ nâng cao SelectionChangeCommitted vào đúng thời điểm.

+0

Người dùng cũng có thể chỉ bắt đầu làm việc trên một phần khác của biểu mẫu và không phải từ khóa. Ngoài ra, phương thức 'cboProperty_SelectionChangeCommitted()' của bạn có tự gọi nó không? Đó không phải là một vòng lặp vô hạn sao? – ulatekh