当控件失焦时,下拉列表会更改所选值

时间:2013-04-18 20:43:48

标签: c# winforms .net-4.0 combobox

我有几个具有相同属性的组合框。

Dropdownstyle : Dropdownlist
AutoCompleteMode: SuggestAppend
AutoCompleteSource: ListItems

例如,我有一个下拉列表cboxStates,它在手动输入的Items Collection中有50个美利坚合众国州。当我键入WI时,它会在WA,WV,WI,WY中突出显示,但是如果我选中/按下输入/鼠标单击另一个控件,则选择WA而不是突出显示的WI。这是完全随机的,它发生在动态绑定的组合框中。而且,他们没有任何事件。

1 个答案:

答案 0 :(得分:1)

这似乎是一个已提交给Connect的问题。有一个解决方法,它扩展了默认的ComboBox控件并修复了问题。扩展的ComboBox代码在Connect站点上格式可怕,所以这里有更好的版本:)

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