2010-01-04 42 views
11

比方說,我們在Windows應用程序下面的代碼:ComboBox.SelectedValue不匹配,顯示文本時,DropDownStyle = DropDownList的在Windows 7

ComboBox comboBox = new ComboBox() 
{ 
    AutoCompleteMode = AutoCompleteMode.SuggestAppend, 
    AutoCompleteSource = AutoCompleteSource.ListItems, 
    DataSource = new string[] { "", "Ark", "Boat", "Bucket" }, 
    DropDownStyle = ComboBoxStyle.DropDownList 
}; 
this.Controls.Add(comboBox); 

TextBox textBox = new TextBox() 
{ 
    Left = comboBox.Right, 
    Top = comboBox.Top, 
    ReadOnly = true 
}; 
textBox.DataBindings.Add("Text", comboBox, "SelectedValue"); 
this.Controls.Add(textBox); 

沒有魔法在這裏,只需綁定到字符串列表的ComboBoxTextBox顯示ComboBoxSelectedValue

當我在ComboBox中輸入「Bucket」並跳開時,出現意外的行爲。由於某些原因,ComboBox顯示「Boat」,但TextBox顯示「Bucket」。我希望他們都顯示「桶」。

如果我將DropDownStyle更改爲DropDown,它的行爲如預期,但我不希望用戶能夠輸入任何他們想要的內容。他們應該只能輸入列表中的項目。

更有趣的是,在輸入「Bucket」和Tab鍵後,如果再次輸入「Bucket」,它將在兩個中都顯示「Bucket」。如果我進行第三次嘗試,則返回到「船」,ComboBox和「文本框」的「桶」。所以它好像是在循環所有B的。

我沒有注意到這一點,直到我最近從XP升級到Windows 7。我不明白這與這有什麼關係,但我反正把它扔掉了。

如果這種行爲是正確的,任何人都可以告訴我該怎麼做才能達到我的預期行爲?

UPDATE這似乎這個與Windows 7的一切行爲與預期在Windows XP模式。其他人可以運行Windows 7嘗試我的代碼,並驗證我不是瘋了嗎?

+0

我把你的代碼準確地拿到了新的表單上,並且不能重現這種行爲。您可能會嘗試連接SelectedIndexChanged事件並引發一些控制檯消息,並查看組合中鍵入的內容。 – TheHurt 2010-01-04 18:55:50

+0

我添加了'comboBox.SelectedIndexChanged + = new EventHandler(delegate {Console.WriteLine(「SelectedIndex = {0}」,comboBox.SelectedIndex);});'和輸出表示'SelectedIndex'變成了「2」,然後到「3」,與「TextBox」顯示的內容相匹配。 – Ecyrb 2010-01-04 19:09:59

+0

如果這是一個可重現的錯誤,您應該將其提交給Microsoft Connect:https://connect.microsoft.com/VisualStudio/ – 2010-01-05 15:01:41

回答

2

hotfix將解決這個問題。

+2

儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的重要部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 – 2013-08-14 04:49:27

+1

那麼這是指向Microsoft發佈的修補程序的下載頁面的鏈接。這裏沒有什麼要補充的,我不希望這個鏈接過期:) – bittusarkar 2013-08-14 08:11:43

6

一種解決方法可以改變DropDownStyleDropDown並添加以下內容:

comboBox.Validating += new CancelEventHandler((o, e) => 
    { 
     e.Cancel = (comboBox.DataSource as string[]).Contains(comboBox.Text) == false; 
    }); 

這將允許用戶輸入任何東西,但它不會讓他們標籤距控制,除非他們鍵入了有效項目。

然而,不愉快的行爲從XP更換到贏7

+1

+1這裏是vb.net版本,爲我工作:'e.Cancel = Not(comboBox.Items.Contains(comboBox.Text))''。 – 2013-08-21 15:07:17

0

我知道,這個反應是很老,但我需要一個答案,這個Windows 7的錯誤。我修修補補周圍的Ecyrb的靜脈,同時並用以下變通上來:

在initForm()的應用程序添加此屬性:

Me.KeyPreview = True 

從哪裏組合框所在位置:

Private mbTab As Boolean 
Private miPrevIndex As Integer = -1 
Private Sub DropDownListEx_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Validating 
    miPrevIndex = Me.SelectedIndex 
    MyBase.OnSelectedIndexChanged(e) 
End Sub 
Private Sub DropDownListEx_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles Me.PreviewKeyDown 
    mbTab = e.KeyCode = Windows.Forms.Keys.Tab 
End Sub 
Protected Overrides Sub OnDropDownClosed(ByVal e As System.EventArgs) 
    MyBase.OnDropDownClosed(e) 
    If Me.SelectedIndex <> miPrevIndex Then 
     If mbTab = True Then 
      Me.SelectedIndex = miPrevIndex 
     Else 
      miPrevIndex = Me.SelectedIndex 
     End If 
     MyBase.OnSelectedIndexChanged(e) 
    End If 
End Sub 

現在,在我的示例中,我正在使用繼承comboBox的自定義控件。所以你需要將它們連接起來以供自己使用。

0

覆蓋OnTextChanged方法,只是不傳遞消息到基地。

protected override void OnTextChanged(EventArgs e) 
{ 
    //Eat the message so it doesn't select an incorrect value. 
} 
1

我遇到了這個問題,發現了一些解決方法。最後,我滾我自己的解決方案作爲一個組合框的子類:

//as noted here: https://connect.microsoft.com/VisualStudio/feedback/details/523272/combobox-does-not-display-selectedvalue-to-user-in-windows-7 
//Windows 7 has issues with ComboBoxStyle.DropDownList mixed with AutoCompleteMode.Append or AutoCompleteMode.SuggestAppend 
//this class seeks to address those problems 
public class BetterComboBox : ComboBox 
{ 
    private int _windows7CorrectedSelectedIndex = -1; 

    private int? _selectedIndexWhenDroppedDown = null; 
    protected override void OnDropDown(EventArgs e) 
    { 
    _selectedIndexWhenDroppedDown = SelectedIndex; 
    base.OnDropDown(e); 
    } 
    private bool _onDropDownClosedProcessing = false; 
    protected override void OnDropDownClosed(EventArgs e) 
    { 
    if (_selectedIndexWhenDroppedDown != null && _selectedIndexWhenDroppedDown != SelectedIndex) 
    { 
     try 
     { 
     _onDropDownClosedProcessing = true; 
     OnSelectionChangeCommitted(e); 
     } 
     finally 
     { 
     _onDropDownClosedProcessing = false; 
     } 
    } 
    base.OnDropDownClosed(e); 
    if (SelectedIndex != _windows7CorrectedSelectedIndex) 
    { 
     SelectedIndex = _windows7CorrectedSelectedIndex; 
     OnSelectionChangeCommitted(e); 
    } 
    } 
    protected override void OnSelectionChangeCommitted(EventArgs e) 
    { 
    if (!_onDropDownClosedProcessing) _windows7CorrectedSelectedIndex = SelectedIndex; 
    _selectedIndexWhenDroppedDown = null; 
    base.OnSelectionChangeCommitted(e); 
    } 
    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
    bool alreadyMatched = true; 
    if (_windows7CorrectedSelectedIndex != SelectedIndex) 
    { 
     _windows7CorrectedSelectedIndex = SelectedIndex; 
     alreadyMatched = false; 
    } 
    base.OnSelectedIndexChanged(e); 

    //when not dropped down, the SelectionChangeCommitted event does not fire upon non-arrow keystrokes due (I suppose) to AutoComplete behavior 
    //this is not acceptable for my needs, and so I have come up with the best way to determine when to raise the event, without causing duplication of the event (alreadyMatched) 
    //and without causing the event to fire when programmatic changes cause SelectedIndexChanged to be raised (_processingKeyEventArgs implies user-caused) 
    if (!DroppedDown && !alreadyMatched && _processingKeyEventArgs) OnSelectionChangeCommitted(e); 
    } 
    private bool _processingKeyEventArgs = false; 
    protected override bool ProcessKeyEventArgs(ref Message m) 
    { 
    try 
    { 
     _processingKeyEventArgs = true; 
     return base.ProcessKeyEventArgs(ref m); 
    } 
    finally 
    { 
     _processingKeyEventArgs = false; 
    } 
    } 
} 
1

我創建了我自己的解決方案,因爲我不認爲爲所有用戶計算機部署修補程序是合理的或可管理的。但是,修補程序問題描述描述了我的問題。例如見下表:

橡子 蘋果



奶酪

如果我選擇開始爲B,如牀一個項目,它會選擇在第一時間開始B會是壞的。這是如果我只鍵入前兩個字符Be(沒有測試打字整個字符串作爲我的真實世界的情況下,這將是不合理的用戶這樣做)。

我有以下設置組合框:
AutoCompleteMode - SuggestAppend,
AutoCompleteSource - listItems中,
DropDownStyle - DropDownList的。

爲了解決這個問題,我做了以下事情,因爲我注意到在SelectedIndexChanged事件期間選擇了期望的值,但沒有選擇Leave事件。

int myDesiredIndexSelection; 

    private void myComboBox_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     myDesiredIndexSelection = myComboBox.SelectedIndex; 
    } 

    private void myComboBox_Leave(object sender, EventArgs e) 
    { 
     myComboBox.SelectedIndex = myDesiredIndexSelection; 
    } 
    private void myForm_KeyUp(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Tab) 
      myComboBox.SelectedIndex = myDesiredIndexSelection; 
    } 

Leave事件似乎解決了按Enter鍵的問題。 KeyUp(KeyDown不起作用)似乎解決了標籤問題。

0

我仍然可以在Windows 10上重現這一點,所以我想我會將我的解決方法添加到列表中。

Private Sub LeaveComboBox(s As Object, e As EventArgs) Handles ComboBox1.Leave 
    Dim sender as ComboBox = DirectCast(s, ComboBox) 

    If sender.DroppedDown Then 
     ' Save the correct item 
     Dim correctSelection as Object = sender.SelectedItem 

     ' The core of the issue seems to be that while searching, Leave is 
     ' triggered before DropDownClosed when you hit the TAB. 
     ' Instead, trigger that now: 
     sender.DroppedDown = False 

     ' Restore the correct item. 
     sender.SelectedItem = correctSelection 
    End If 
End Sub 
相關問題