C# 保留在鼠标单击时触发的事件,但不在方向键上触发

C# 保留在鼠标单击时触发的事件,但不在方向键上触发,c#,winforms,C#,Winforms,所以我有我的应用程序的截图。要解释发生了什么,我使用leave事件在没有从列表中选择有效项时显示MessageBox。目前,如果我开始键入,然后尝试用鼠标选择项目,它会出现,但如果我使用箭头键,它不会出现。例如,在这个屏幕截图中,我输入“cen”,我想从列表中选择“Camp Chicken Bourt 10.5oz(17960)”,如果我使用方向键,然后按enter键,这是可以的,但如果我使用鼠标,则事件下方的消息框会被弹出。我还注意到,它允许在MessageBox关闭后通过鼠标左键进行选择。在

所以我有我的应用程序的截图。要解释发生了什么,我使用leave事件在没有从列表中选择有效项时显示MessageBox。目前,如果我开始键入,然后尝试用鼠标选择项目,它会出现,但如果我使用箭头键,它不会出现。例如,在这个屏幕截图中,我输入“cen”,我想从列表中选择“Camp Chicken Bourt 10.5oz(17960)”,如果我使用方向键,然后按enter键,这是可以的,但如果我使用鼠标,则事件下方的消息框会被弹出。我还注意到,它允许在MessageBox关闭后通过鼠标左键进行选择。在用户关闭MessageBox之后选择一个项目非常麻烦。这有什么办法吗?下图是“离开”事件函数

更新为suggestComboBox

  using System.Windows.Forms;

namespace AutoCompleteComboBox
{
public class SuggestComboBox : ComboBox
{
    #region fields and properties

    private readonly ListBox _suggLb = new ListBox { Visible = false, TabStop = false };
    private readonly BindingList<string> _suggBindingList = new BindingList<string>();
    private Expression<Func<ObjectCollection, IEnumerable<string>>> _propertySelector;
    private Func<ObjectCollection, IEnumerable<string>> _propertySelectorCompiled;
    private Expression<Func<string, string, bool>> _filterRule;
    private Func<string, bool> _filterRuleCompiled;
    private Expression<Func<string, string>> _suggestListOrderRule;
    private Func<string, string> _suggestListOrderRuleCompiled;

    public int SuggestBoxHeight
    {
        get { return _suggLb.Height; }
        set { if (value > 0) _suggLb.Height = value; }
    }

    /// <summary>
    /// If the item-type of the ComboBox is not string,
    /// you can set here which property should be used
    /// </summary>
    public Expression<Func<ObjectCollection, IEnumerable<string>>> PropertySelector
    {
        get { return _propertySelector; }
        set
        {
            if (value == null) return;
            _propertySelector = value;
            _propertySelectorCompiled = value.Compile();
        }
    }

    ///<summary>
    /// Lambda-Expression to determine the suggested items
    /// (as Expression here because simple lamda (func) is not serializable)
    /// <para>default: case-insensitive contains search</para>
    /// <para>1st string: list item</para>
    /// <para>2nd string: typed text</para>
    ///</summary>
    public Expression<Func<string, string, bool>> FilterRule
    {
        get { return _filterRule; }
        set
        {
            if (value == null) return;
            _filterRule = value;
            _filterRuleCompiled = item => value.Compile()(item, Text);
        }
    }

    ///<summary>
    /// Lambda-Expression to order the suggested items
    /// (as Expression here because simple lamda (func) is not serializable)
    /// <para>default: alphabetic ordering</para>
    ///</summary>
    public Expression<Func<string, string>> SuggestListOrderRule
    {
        get { return _suggestListOrderRule; }
        set
        {
            if (value == null) return;
            _suggestListOrderRule = value;
            _suggestListOrderRuleCompiled = value.Compile();
        }
    }

    #endregion

    /// <summary>
    /// ctor
    /// </summary>
    public SuggestComboBox()
    {
        // set the standard rules:
        _filterRuleCompiled = s => s.ToLower().Contains(Text.Trim().ToLower());
        _suggestListOrderRuleCompiled = s => s;
        _propertySelectorCompiled = collection => collection.Cast<string>();

        _suggLb.DataSource = _suggBindingList;
        _suggLb.Click += SuggLbOnClick;

        ParentChanged += OnParentChanged;
    }

    /// <summary>
    /// the magic happens here ;-)
    /// </summary>
    /// <param name="e"></param>
    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);

        if (!Focused) return;

        _suggBindingList.Clear();
        _suggBindingList.RaiseListChangedEvents = false;
        _propertySelectorCompiled(Items)
             .Where(_filterRuleCompiled)
             .OrderBy(_suggestListOrderRuleCompiled)
             .ToList()
             .ForEach(_suggBindingList.Add);
        _suggBindingList.RaiseListChangedEvents = true;
        _suggBindingList.ResetBindings();

        _suggLb.Visible = _suggBindingList.Any();

        if (_suggBindingList.Count == 1 &&
                    _suggBindingList.Single().Length == Text.Trim().Length)
        {
            Text = _suggBindingList.Single();
            Select(0, Text.Length);
            _suggLb.Visible = false;
        }
    }

    #region size and position of suggest box

    /// <summary>
    /// suggest-ListBox is added to parent control
    /// (in ctor parent isn't already assigned)
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnParentChanged(object sender, EventArgs e)
    {
        Parent.Controls.Add(_suggLb);
        Parent.Controls.SetChildIndex(_suggLb, 0);
        _suggLb.Top = Top + Height - 3;
        _suggLb.Left = Left + 3;
        _suggLb.Width = Width - 20;
        _suggLb.Font = new Font("Segoe UI", 9);
    }

    protected override void OnLocationChanged(EventArgs e)
    {
        base.OnLocationChanged(e);
        _suggLb.Top = Top + Height - 3;
        _suggLb.Left = Left + 3;
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        _suggLb.Width = Width - 20;
    }

    #endregion

    #region visibility of suggest box

    protected override void OnLostFocus(EventArgs e)
    {
        // _suggLb can only getting focused by clicking (because TabStop is off)
        // --> click-eventhandler 'SuggLbOnClick' is called
        if (!_suggLb.Focused)
            HideSuggBox();
        base.OnLostFocus(e);
    }

    private void SuggLbOnClick(object sender, EventArgs eventArgs)
    {
        Text = _suggLb.Text;
        Focus();
    }

    private void HideSuggBox()
    {
        _suggLb.Visible = false;
    }

    protected override void OnDropDown(EventArgs e)
    {
        HideSuggBox();
        base.OnDropDown(e);
    }

    #endregion

    #region keystroke events

    /// <summary>
    /// if the suggest-ListBox is visible some keystrokes
    /// should behave in a custom way
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
    {
        if (!_suggLb.Visible)
        {
            base.OnPreviewKeyDown(e);
            return;
        }

        switch (e.KeyCode)
        {
            case Keys.Down:
                if (_suggLb.SelectedIndex < _suggBindingList.Count - 1)
                    _suggLb.SelectedIndex++;
                return;
            case Keys.Up:
                if (_suggLb.SelectedIndex > 0)
                    _suggLb.SelectedIndex--;
                return;
            case Keys.Enter:
                Text = _suggLb.Text;
                Select(0, Text.Length);
                _suggLb.Visible = false;
                return;
            case Keys.Escape:
                HideSuggBox();
                return;
        }

        base.OnPreviewKeyDown(e);
    }

    private static readonly Keys[] KeysToHandle = new[] { Keys.Down, Keys.Up, Keys.Enter, Keys.Escape };
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        // the keysstrokes of our interest should not be processed be base class:
        if (_suggLb.Visible && KeysToHandle.Contains(keyData))
            return true;
        return base.ProcessCmdKey(ref msg, keyData);
    }

    #endregion
}
使用System.Windows.Forms;
名称空间自动完成组合框
{
公共类SuggestComboBox:ComboBox
{
#区域字段和属性
私有只读列表框_suggLb=new ListBox{Visible=false,TabStop=false};
私有只读绑定列表_suggBindingList=new BindingList();
私有表达式属性选择器;
私有功能属性选择或组合;
私有表达式过滤规则;
已编译的专用函数filterrule;
私有表达式_suggestListOrderRule;
已编译的专用Func_SuggestListOrderRule;
公共int SuggestBoxHeight
{
获取{return\u suggLb.Height;}
设置{if(value>0)_suggLb.Height=value;}
}
/// 
///如果组合框的项目类型不是字符串,
///您可以在此处设置应使用的属性
/// 
公共表达式属性选择器
{
获取{return}propertySelector;}
设置
{
if(value==null)返回;
_属性选择器=值;
_propertySelectorCompiled=value.Compile();
}
}
///
///Lambda表达式来确定建议的项目
///(此处为表达式,因为简单lamda(func)不可序列化)
///默认值:不区分大小写包含搜索
///第一个字符串:列表项
///第二个字符串:键入的文本
///
公共表达式筛选器规则
{
获取{return\u filterRule;}
设置
{
if(value==null)返回;
_filterRule=值;
_filterRuleCompiled=item=>value.Compile()(项,文本);
}
}
///
///Lambda表达式对建议的项目进行排序
///(此处为表达式,因为简单lamda(func)不可序列化)
///默认值:字母顺序
///
公共表达式SuggestListOrderRule
{
获取{return\u suggestListOrderRule;}
设置
{
if(value==null)返回;
_suggestListOrderRule=值;
_suggestListOrderRuleCompiled=value.Compile();
}
}
#端区
/// 
///执行器
/// 
公共建议组合框()
{
//制定标准规则:
_filterRuleCompiled=s=>s.ToLower().Contains(Text.Trim().ToLower());
_suggestListOrderRuleCompiled=s=>s;
_propertySelectorCompiled=collection=>collection.Cast();
_suggLb.DataSource=\u suggBindingList;
_suggLb.Click+=SuggLbOnClick;
ParentChanged+=OnParentChanged;
}
/// 
///魔法就发生在这里;-)
/// 
/// 
受保护的覆盖void OnTextChanged(事件参数e)
{
base.OnTextChanged(e);
如果(!聚焦)返回;
_suggBindingList.Clear();
_suggBindingList.RaiseListChangedEvents=false;
_属性选择或组合(项目)
.Where(_filterRuleCompiled)
.OrderBy(_suggestListOrderRuleCompiled)
托利斯先生()
.ForEach(_suggBindingList.Add);
_suggBindingList.RaiseListChangedEvents=true;
_suggBindingList.ResetBindings();
_suggLb.Visible=\u suggBindingList.Any();
如果(_suggBindingList.Count==1&&
_suggBindingList.Single().Length==Text.Trim().Length)
{
Text=_suggBindingList.Single();
选择(0,文本长度);
_suggLb.Visible=false;
}
}
#建议框的区域大小和位置
/// 
///建议将列表框添加到父控件
///(在ctor中,尚未指定父项)
/// 
/// 
/// 
private void OnParentChanged(对象发送方,事件参数e)
{
Parent.Controls.Add(_suggLb);
Parent.Controls.SetChildIndex(_-suggLb,0);
_suggLb.Top=顶部+高度-3;
_suggLb.Left=左+3;
_宽度=宽度-20;
_字体=新字体(“Segoe UI”,9);
}
受保护的覆盖无效OnLocationChanged(事件参数e)
{
基础。位置改变(e);
_suggLb.Top=顶部+高度-3;
_suggLb.Left=左+3;
}
IzeChanged上的受保护覆盖无效(EventArgs e)
{
基地.OnSizeChanged(e);
_宽度=宽度-20;
}
#端区
#建议框的区域可见性
受保护的覆盖void OnLostFocus(事件参数e)
{
//_suggLb只能通过单击获得焦点(因为TabStop已关闭)
//-->click eventhandler调用“SuggLbOnClick”
如果(!\u suggLb.Focused)
hidesugbox();
base.OnLostFocus(e);
}
私有void SuggLbOnClick(对象发送方,EventArgs EventArgs)
{
Text=_suggLb.Text;
焦点();
}
私有void HideSuggBox()
{
_suggLb.Visible=false;
}
受保护的覆盖无效OnDropDown(事件参数e)
{
hidesugbox();
基础.降速(e);
}
#端区
#区域击键事件
/// 
///如果建议列表框可见,则会出现一些按键
///应该按习惯行事
/// 
/// 
受保护的
  using System.Windows.Forms;

namespace AutoCompleteComboBox
{
public class SuggestComboBox : ComboBox
{
    #region fields and properties

    private readonly ListBox _suggLb = new ListBox { Visible = false, TabStop = false };
    private readonly BindingList<string> _suggBindingList = new BindingList<string>();
    private Expression<Func<ObjectCollection, IEnumerable<string>>> _propertySelector;
    private Func<ObjectCollection, IEnumerable<string>> _propertySelectorCompiled;
    private Expression<Func<string, string, bool>> _filterRule;
    private Func<string, bool> _filterRuleCompiled;
    private Expression<Func<string, string>> _suggestListOrderRule;
    private Func<string, string> _suggestListOrderRuleCompiled;

    public int SuggestBoxHeight
    {
        get { return _suggLb.Height; }
        set { if (value > 0) _suggLb.Height = value; }
    }

    /// <summary>
    /// If the item-type of the ComboBox is not string,
    /// you can set here which property should be used
    /// </summary>
    public Expression<Func<ObjectCollection, IEnumerable<string>>> PropertySelector
    {
        get { return _propertySelector; }
        set
        {
            if (value == null) return;
            _propertySelector = value;
            _propertySelectorCompiled = value.Compile();
        }
    }

    ///<summary>
    /// Lambda-Expression to determine the suggested items
    /// (as Expression here because simple lamda (func) is not serializable)
    /// <para>default: case-insensitive contains search</para>
    /// <para>1st string: list item</para>
    /// <para>2nd string: typed text</para>
    ///</summary>
    public Expression<Func<string, string, bool>> FilterRule
    {
        get { return _filterRule; }
        set
        {
            if (value == null) return;
            _filterRule = value;
            _filterRuleCompiled = item => value.Compile()(item, Text);
        }
    }

    ///<summary>
    /// Lambda-Expression to order the suggested items
    /// (as Expression here because simple lamda (func) is not serializable)
    /// <para>default: alphabetic ordering</para>
    ///</summary>
    public Expression<Func<string, string>> SuggestListOrderRule
    {
        get { return _suggestListOrderRule; }
        set
        {
            if (value == null) return;
            _suggestListOrderRule = value;
            _suggestListOrderRuleCompiled = value.Compile();
        }
    }

    #endregion

    /// <summary>
    /// ctor
    /// </summary>
    public SuggestComboBox()
    {
        // set the standard rules:
        _filterRuleCompiled = s => s.ToLower().Contains(Text.Trim().ToLower());
        _suggestListOrderRuleCompiled = s => s;
        _propertySelectorCompiled = collection => collection.Cast<string>();

        _suggLb.DataSource = _suggBindingList;
        _suggLb.Click += SuggLbOnClick;

        ParentChanged += OnParentChanged;
    }

    /// <summary>
    /// the magic happens here ;-)
    /// </summary>
    /// <param name="e"></param>
    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);

        if (!Focused) return;

        _suggBindingList.Clear();
        _suggBindingList.RaiseListChangedEvents = false;
        _propertySelectorCompiled(Items)
             .Where(_filterRuleCompiled)
             .OrderBy(_suggestListOrderRuleCompiled)
             .ToList()
             .ForEach(_suggBindingList.Add);
        _suggBindingList.RaiseListChangedEvents = true;
        _suggBindingList.ResetBindings();

        _suggLb.Visible = _suggBindingList.Any();

        if (_suggBindingList.Count == 1 &&
                    _suggBindingList.Single().Length == Text.Trim().Length)
        {
            Text = _suggBindingList.Single();
            Select(0, Text.Length);
            _suggLb.Visible = false;
        }
    }

    #region size and position of suggest box

    /// <summary>
    /// suggest-ListBox is added to parent control
    /// (in ctor parent isn't already assigned)
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnParentChanged(object sender, EventArgs e)
    {
        Parent.Controls.Add(_suggLb);
        Parent.Controls.SetChildIndex(_suggLb, 0);
        _suggLb.Top = Top + Height - 3;
        _suggLb.Left = Left + 3;
        _suggLb.Width = Width - 20;
        _suggLb.Font = new Font("Segoe UI", 9);
    }

    protected override void OnLocationChanged(EventArgs e)
    {
        base.OnLocationChanged(e);
        _suggLb.Top = Top + Height - 3;
        _suggLb.Left = Left + 3;
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        _suggLb.Width = Width - 20;
    }

    #endregion

    #region visibility of suggest box

    protected override void OnLostFocus(EventArgs e)
    {
        // _suggLb can only getting focused by clicking (because TabStop is off)
        // --> click-eventhandler 'SuggLbOnClick' is called
        if (!_suggLb.Focused)
            HideSuggBox();
        base.OnLostFocus(e);
    }

    private void SuggLbOnClick(object sender, EventArgs eventArgs)
    {
        Text = _suggLb.Text;
        Focus();
    }

    private void HideSuggBox()
    {
        _suggLb.Visible = false;
    }

    protected override void OnDropDown(EventArgs e)
    {
        HideSuggBox();
        base.OnDropDown(e);
    }

    #endregion

    #region keystroke events

    /// <summary>
    /// if the suggest-ListBox is visible some keystrokes
    /// should behave in a custom way
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
    {
        if (!_suggLb.Visible)
        {
            base.OnPreviewKeyDown(e);
            return;
        }

        switch (e.KeyCode)
        {
            case Keys.Down:
                if (_suggLb.SelectedIndex < _suggBindingList.Count - 1)
                    _suggLb.SelectedIndex++;
                return;
            case Keys.Up:
                if (_suggLb.SelectedIndex > 0)
                    _suggLb.SelectedIndex--;
                return;
            case Keys.Enter:
                Text = _suggLb.Text;
                Select(0, Text.Length);
                _suggLb.Visible = false;
                return;
            case Keys.Escape:
                HideSuggBox();
                return;
        }

        base.OnPreviewKeyDown(e);
    }

    private static readonly Keys[] KeysToHandle = new[] { Keys.Down, Keys.Up, Keys.Enter, Keys.Escape };
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        // the keysstrokes of our interest should not be processed be base class:
        if (_suggLb.Visible && KeysToHandle.Contains(keyData))
            return true;
        return base.ProcessCmdKey(ref msg, keyData);
    }

    #endregion
}
 void fillCari()//fill Cari-med dropdown with values
    {
        try
        {

            string connectionString = "Data Source=CMDLAP126;Initial Catalog=Carimed_Inventory;User ID = sa; Password = 123456;";
            SqlConnection con2 = new SqlConnection(connectionString);
            con2.Open();
            string query = "SELECT DISTINCT Item_Description FROM dbo.Carimed"; 
            SqlCommand cmd2 = new SqlCommand(query, con2);

            SqlDataReader dr2 = cmd2.ExecuteReader();
            while (dr2.Read())
            {
                string cari_des = dr2.GetString(dr2.GetOrdinal("Item_Description"));
                suggestComboBox1.Items.Add(cari_des);
                suggestComboBox1.Text.Trim();
            }
            //con2.Close();
        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.ToString());
        }
   string query = "SELECT DISTINCT Item_Description FROM dbo.Carimed";
   string query = "SELECT Item_Description FROM dbo.Carimed";