2013-01-23 15 views
7

Oto krótki program, który odtwarza problem, który właśnie napotkałem. Zostało to skompilowane pod MS Windows 7 z .NET 4.0, na wszelki wypadek, który robi różnicę.Zdarzenie ComboBox SelectionChangeCommitted nie działa z funkcją Autouzupełnianie

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"); 
    } 
} 

Kliknij tekstową część pola kombi i wpisz "A". Otrzymasz listę sugestii autouzupełniania. Kliknij jedną z opcji myszką. Zdarzenie SelectionChangeCommitted się nie stało!

Wybierz element menu bez korzystania z funkcji autouzupełniania. Otrzymasz komunikat z informacją o zdarzeniu SelectionChangeCommitted!

Biorąc pod uwagę, że wybór został zmieniony przez użytkownika w obu przypadkach, czy w obu przypadkach nie należy wywoływać numeru SelectionChangeCommitted?

Użycie zdarzenia nie jest opcją, ponieważ w przypadku aplikacji znajdującej się za tym przykładem w puszkach chcę, aby miało to miejsce tylko wtedy, gdy użytkownik dokona wyboru, a nie gdy zostanie ustawione programowo.

+0

Wypróbowałem twój kod, ale wszystko było w porządku. – spajce

+0

Dowolna szansa [ten numer] (http://stackoverflow.com/questions/13291945/winforms-combobox-loses-autocomplete-value-on-lostfocus) w ogóle pomaga? – Guvante

+0

@spajce: Uruchomiłem przykładowy kod źródłowy tak, jak napisałem i powieliłem opisane zachowanie. Win 8, VS 2010, .NET 4 Client Profile. Zwróć uwagę, że oczekiwane zachowanie pojawia się podczas wybierania wartości jako części automatycznego uzupełniania. – Guvante

Odpowiedz

2

Korzystanie zdarzenie SelectedIndexChanged nie jest opcją, ponieważ dla aplikacji za tym puszkach przykład, tylko chcę to się stało, gdy użytkownik dokonuje wyboru, a nie kiedy jest on ustawiony programowo.

Można to również osiągnąć, pisząc metodę owijania w celu zmiany zaznaczenia, które tymczasowo wyłącza wydarzenie.

Niestety, nie wiem od ręki rozwiązania problemu, który nie jest uruchamiany w przypadku bardziej ogólnego przypadku (np. Gdy nie masz kontroli nad ComboBox lub w jaki sposób jest on dostępny).

EDIT:

Zrobiłem streamer wszystkich zdarzeń, które ComboBox połączeń, a nie wydaje się, że jakiekolwiek inne zdarzenie, zrobi to, czego szukasz. Jedyne rozwiązanie, jakie mogę wymyślić, będzie polegać na włączaniu zdarzeń, które uruchamia autouzupełnianie. Trudność polega na tym, aby wiedzieć, jakie są te zdarzenia, ponieważ nie wydają się one wyzwalać ComboBox z tego, co pokazują moje drobne testy.

1

FYI, tutaj było najlepsze rozwiązanie, jakie kiedykolwiek wymyśliłem. Oczywiście jest to program obsługi zdarzeń Leave w podklasie ComboBox. Zdarzenie SelectionChangeCommitted nie występuje po kliknięciu myszą, ale przynajmniej dzieje się podczas normalnego przepływu interakcji 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

Jeśli ktoś dostał ten problem, proponujemy rozwiązanie, które działa dobrze dla mnie ...

Pomyśl o mnie, aby zaakceptować sugerują Combo-box z ogólnie użytkownik musi wprowadzić w dół klawisz Enter.

Możesz napisać do KeyDown zdarzenia mienia Combo-box, coś takiego:

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

Będzie podnieść SelectionChangeCommitted o właściwym czasie.

+0

Użytkownik może również rozpocząć pracę nad inną częścią formularza, a nie w ogóle. Czy twoja metoda 'cboProperty_SelectionChangeCommitted()' wywołuje samą siebie? Czy to nie jest nieskończona pętla? – ulatekh

Powiązane problemy