2014-09-04 54 views
2

我有一個TextChanged事件在我的ComboBox像;如何在選擇組合框中的項目時防止出現TextChanged事件?

private void comboBox1_TextChanged(object sender, EventArgs e) 
{ 
    foreach (var item in comboBox1.Items.Cast<string>().ToList()) 
    { 
     comboBox1.Items.Remove(item); 
    } 

    foreach (string item in InputBox.AutoCompleteCustomSource.Cast<string>().Where(s => s.Contains(comboBox1.Text)).ToList()) 
    { 
     comboBox1.Items.Add(item); 
    } 
} 

爲了進一步說明,當我改變組合框的文字,我想string值包含AutoCompleteCustomSourceInputBox(這是TextBox)。

它能正常工作,當我搜索他們,但是當我選擇該項目,明顯0123'事件再次觸發和Text屬性Combobox將重置。

如何解決這個問題?

+0

一個廉價的勝利將是設置一個布爾值在SelectionChanged事件......我相信在這兩種情況下發送者是一回事嗎? – Sayse 2014-09-04 10:14:45

+0

@Sayse你說'SelectedValueCahnged'事件?當我選擇一個結果時,'comboBox1_TextChanged'和'comboBox1_SelectedValueChanged'事件'sender'''Text'屬性都是空字符串。 – 2014-09-04 13:13:30

+0

是的我在想布爾的想法,你需要在[SelectedValueChanged](http://msdn.microsoft.com/en-us/library/system.windows.forms。listcontrol.selectedvaluechanged(v = vs.110).aspx)事件(爲false)表明您希望繞過事件。我的第二個想法是,發件人可能在輸入時爲null,而來自更改後的選擇時則爲combobox。 – Sayse 2014-09-04 13:18:43

回答

7

如果我理解正確的話,我想你想隱藏組合框的TextChange事件。如果是,則可以創建由ComboBox繼承的自定義控件並覆蓋TextChange事件。

public partial class MyCombo : ComboBox 
{ 
    public MyCombo() 
    { 
     InitializeComponent(); 
    } 
    bool bFalse = false; 
    protected override void OnTextChanged(EventArgs e) 
    { 
     //Here you can handle the TextChange event if want to suppress it 
     //just place the base.OnTextChanged(e); line inside the condition 
     if (!bFalse) 
      base.OnTextChanged(e); 
    } 
    protected override void OnSelectionChangeCommitted(EventArgs e) 
    { 
     bFalse = true; 
     base.OnSelectionChangeCommitted(e); 
    } 
    protected override void OnTextUpdate(EventArgs e) 
    { 
     base.OnTextUpdate(e); 
     bFalse = false; //this event will be fire when user types anything. but, not when user selects item from the list. 
    } 
} 

編輯: 另一個簡單的soution是使用,而不是TextChangeTextUpdate事件,並保持你的組合框,因爲它是沒有創建另一個自定義控件。

private void myCombo1_TextUpdate(object sender, EventArgs e) 
{ 
    foreach (var item in myCombo1.Items.Cast<string>().ToList()) 
    { 
     myCombo1.Items.Remove(item); 
    } 

    foreach (string item in myCombo1.AutoCompleteCustomSource.Cast<string>().Where(s => s.Contains(myCombo1.Text)).ToList()) 
    { 
     myCombo1.Items.Add(item); 
    } 
} 

TextUpdate僅當用戶在組合框中鍵入任何內容時,纔會調用事件。但是,不是當用戶從下拉列表中選擇項目時。所以,這不會增加項目。

如果您希望在兩種情況下都返回所有匹配的項目(Upper和Lower),您還可以更改where條件。假設你在列表1. Microsoft Sql Server, 2. microsoft office中有兩個項目,那麼如果我只輸入microsoft,結果會是什麼。

Where(s => s.ToLower().Contains(comboBox1.Text.ToLower())) 

Sample Code

enter image description here

+0

但是你不能用'base'在'OnSelectionChangeCommitted'裏面調用'OnSelectionChangeCommitted'。 – 2014-09-04 12:35:03

+0

我還沒有調用它..一旦你從intellisense中選擇了方法,覆蓋它的方法會自動生成。 – Shell 2014-09-04 12:37:40

+0

爲什麼你需要另一個MyCombo類?因爲當你在其中使用'InitializeComponent'時,它會中斷窗體窗體的設計器代碼。 – 2014-09-04 13:02:44

0

正如@Sayse已經說過:

添加一個布爾值:

private bool codeCalled = new bool(); 

在你框TextChanged:

if(codeCalled == true) 
{ 
    codeCalled = false; 
    return; 
} 
else 
{ 
    codeCalled = true; 
    //your foreachcode here   
} 

這應該做的伎倆。

測試並正在工作。

還測試和工作,也沒有飄逸:

private void textBox_TextChanged(object sender, EventArgs e) 
{ 
    textBox.TextChanged -= textBox_TextChanged; 

    //yourcode 

    textBox.TextChanged += textBox_TextChanged; 
} 
+0

但是這不起作用,因爲每次'TextChanged'觸發時,默認情況下'codeCalled'都將爲'false'。這就是爲什麼每一次這個'else'部分都會起作用,並且項目會再次被清除。 – 2014-09-04 10:58:27

+0

是的......以及更新後的答案已經過測試並且可以正常工作。 +1德米特里,當我寫這些時,不知道我的想法在哪裏。 – DatRid 2014-09-04 11:16:07

相關問題