2016-10-07 2 views
2

Я пытаюсь реализовать свой собственный класс ComboBox на C#, поскольку до 3.5 NET Framework (если я не ошибаюсь) поиск предложений выполняется с помощью функции «StartWith» (т. Е. Если список содержит «Doe, John» и типы пользователей «John», этот элемент не отображается). В основном я добавляю или удаляю элементы в событии изменения текста, получая их из исходного содержимого списка. Все работает очень хорошо для того, что я ищу, единственная проблема заключается в том, что когда ComboBox вызывается, элемент все еще выбирается, даже если он не равен вставленному тексту. Следуя примеру, который я сделал, я хочу, чтобы «Doe, John» был выбран (и установлен как свойство ComboBox.Text), только если пользователь нажал на него, если пользователь просто набрал «Джон», и ни один элемент не был строго равен ему (не только), то свойство Text должно оставаться в качестве пользователя, вставленного им. Вот код моего производного классаC# предотвращение пользовательских combobox от автоматического выбора элемента

public class customTB : ComboBox 
{ 
    private object[] startlist; 
    public customTB() : base() 
    { 
     this.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None; 
     this.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None; 
     this.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown; 
     this.Sorted = true; 
     this.KeyPress += customTB_KeyPress; 
     this.TextChanged += customTB_TextChanged; 
     this.Enter += customTB_Enter; 
    } 

    void customTB_Enter(object sender, EventArgs e) 
    { 
     this.DroppedDown = (this.Items.Count > 0); 
    } 

    void customTB_TextChanged(object sender, EventArgs e) 
    { 
     UpdateList(); 
    } 

    void customTB_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     this.DroppedDown = (this.Items.Count>0); 
    } 

    void UpdateList() 
    { 
     if (this.startlist == null) 
     { 
      //get starting lists elems 
      this.startlist = new Object[this.Items.Count]; 
      this.Items.CopyTo(this.startlist, 0); 
     } 
     this.BeginUpdate(); 
     foreach (object o in startlist) 
     { 
      if (o.ToString().Contains(this.Text)) 
      { 
       if (!this.Items.Contains(o)) 
        this.Items.Add(o); 
      } 
      else if (this.Items.Contains(o)) 
       this.Items.Remove(o); 
     } 
     this.EndUpdate(); 
    } 
} 

Если пробовали, в любое время вы пытаетесь выйти из ComboBox, текст будет выделен и его значение устанавливается на элемент. В качестве примера того, что я хотел бы иметь, является: Элементы содержат «Doe John», «Smith John», «Smith Marie». , если пользовательские типы «Джон», а затем выпадающие элементы - «Doe John» и «Smith John», но если он не нажимает ни на один из выпадающих элементов и не выходит из ComboBox (т.е. нажимает на него), текст остается «John»

ответ

0

Есть одна логическая переменная itemClicked

  • Set itemClicked ложь внутри Введите обработчик событий
  • Set itemClicked истина внутри обработчика событий SelectionChangeCommitted
  • Set Text свойство String.Empty если не itemClicked внутри обработчика событий DropDownClosed
+0

Я попытался, поведение по-прежнему остается прежним, когда я пытаюсь выйти из поля со списком, весь текст выделен и элемент заменяет текст, вставленный в элемент управления –

+0

@Alessandro Perla. Да, вы правы, однако он удаляется, как только фокус покидает поле со списком. Но если вы хотите, чтобы он был удален сразу, вы можете использовать обработчик события DropDownClosed вместо обработчика обработанных событий. Я также изменил ответ выше. – Rupesh

+0

Правда, хорошо обходное решение, спасибо. Единственное примечание, которое я хотел бы добавить, это то, что я хотел иметь входной текст, когда раскрывающийся список закрыт, а не пустая строка, поэтому я настраиваю строчную строковую переменную, копируя в этой переменной значение свойства Text в событии TextChanged и устанавливая он возвращается в DropDownClosed вместо String.Empty. Спасибо! –

Смежные вопросы