2016-12-20 2 views
1

So habe ich diesen Screenshot aus meiner Anwendung. Um zu erklären, was passiert, verwende ich das leave-Ereignis, um eine MessageBox anzuzeigen, wenn ein gültiges Element nicht aus der Liste ausgewählt ist. Momentan kommt es auf, wenn ich anfange zu tippen und dann versuche, das Element mit der Maus auszuwählen, aber nicht, wenn ich die Pfeiltasten benutze. Für z. In diesem Screenshot gebe ich "cen" ein und ich möchte "Camp Chicken Broth 10,5 oz (17960)" aus der Liste auswählen, wenn ich die Richtungstasten benutze und dann Enter drücke, ist das in Ordnung, aber wenn ich die Maus benutze, dann die MessageBox unter Ereignis wird ausgelöst. Ich merke auch, dass es die Auswahl mit dem linken Mausklick ermöglicht, nachdem die MessageBox geschlossen wurde. Das Auswählen eines Elements, nachdem der Benutzer die MessageBox geschlossen hat, ist ziemlich störend. Gibt es dafür eine Arbeit? Unter dem Bild ist die Funktion Event verlassenLassen Ereignis ausgelöst wird auf Mausklick, aber nicht auf Richtungstasten

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!"); 
     } 
    } 

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

Aktualisiert}

+0

Versuchen Sie Textchanged oder SelectedValueChanged statt Leave –

+0

Aber wenn ich die benutze sie nicht tun, was ich allerdings will. Ich möchte, dass es die MessageBox aufruft, wenn keine Übereinstimmung in der ComboBox-Werteliste gefunden wird. @RobertoPegoraro – Jevon

+0

Verwenden Sie weitere Ereignisse außer Leave? Weil ich Ihren Fehler hier nicht reproduzieren konnte –

Antwort

0

Okay, ich meine Schritte und alles nachvollzogen und in Erinnerung hatte ich meine Abfrage geändert und Seitdem fing ich an, das Problem zu haben. Ursprünglich war dies die Funktion, die die comboBox oben mit Werten:

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

Diese besondere Linie war die Frage: „DISTINCT“

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

Stellt sich heraus, es hat etwas damit zu tun, Ist nicht ganz sicher, warum es zu entfernen und es so weit gelöst mein Problem Wechsel:

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