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

时间:2016-12-20 13:15:21

标签: c# winforms

所以我从我的应用程序中获取了这个截图。为了解释发生了什么,当我没有从列表中选择有效项时,我正在使用leave事件来显示MessageBox。目前,如果我开始输入然后尝试用鼠标选择项目,但是如果我使用箭头键则不会出现。例如。在这个屏幕截图中,我输入“cen”,我想从列表中选择“Camp Chicken Broth 10.5oz(17960)”,如果我使用方向键然后点击输入它很好但是如果我使用鼠标那么引发下面的MessageBox事件。我还注意到,它允许在MessageBox关闭后通过鼠标左键单击进行选择。用户关闭MessageBox后选择一个项目是非常麻烦的。有没有解决这个问题?图像下方是离开事件功能

private void suggestComboBox1_Leave(object sender, EventArgs e)
    {
        ComboBox c_med = (ComboBox)sender;
        if (!suggestComboBox1.Items.Contains(c_med.Text))
        {
            MessageBox.Show("Not a valid Cari-med Item!");
        }
    }

使用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
}

}

1 个答案:

答案 0 :(得分:0)

好的,我回顾了我的步骤和一切,并记得我已经改变了我的查询,从那时起我开始遇到这个问题。最初这是使用值填充上面的comboBox的函数:

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

原来它与“DISTINCT”有关。我不完全确定为什么删除它并将其更改为解决了我的问题:

   string query = "SELECT Item_Description FROM dbo.Carimed";