Reputation: 61
I have a C# WinForms application, and I succeed in filtering ComboBox items by writing any part of its items and pressing enter after inputing the text part, using this code:
private void detailsGridView_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
var comboBox = e.Control as ComboBox;
if (comboBox != null)
{
comboBox.DropDownStyle = ComboBoxStyle.DropDown;
comboBox.PreviewKeyDown += ComboBox_PreviewKeyDown;
}
}
private void ComboBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if ((e.KeyCode & e.KeyData) == Keys.Return)
{
if (((ComboBox)sender).SelectedItem == null)
{
e.IsInputKey = true;
((ComboBox)sender).DataSource = accounts
.Where(a => a.Name.Contains(((ComboBox)sender).Text))
.ToList();
((ComboBox)sender).DroppedDown = true;
}
}
}
Then I encountered a problem in line ((ComboBox)sender).DroppedDown = true where the list was dropping and closing instantly.
I noticed while debugging that KeyDown event raised twice so I tried a flag variable to check the second raise and cancel, but wasn't useful. I tried many other approaches like:
But the list still closing instantly after it had appeared.
What is the right approach in this context?
Edit:
I noticed that when I remove condition line if ((e.KeyCode & e.KeyData) == Keys.Return)
The function not work correctly but also the dropdown list stay open.
Upvotes: 0
Views: 88
Reputation: 61
I solved this issue by adding a separate method for handling filter, and another method for handling KeyDown issue, this is the code:
private void detailsGridView_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox comboBox)
{
comboBox.DropDownStyle = ComboBoxStyle.DropDown;
comboBox.KeyDown += ComboBox_KeyDown;
comboBox.PreviewKeyDown += ComboBox_PreviewKeyDown;
}
}
private void ComboBox_PreviewKeyDown(object sender,
PreviewKeyDownEventArgs e)
{
if ((e.KeyCode & e.KeyData) == Keys.Enter)
if (((ComboBox)sender).SelectedItem == null)
e.IsInputKey = true;
}
private void ComboBox_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode & e.KeyData) == Keys.Enter)
{
if (((ComboBox)sender).SelectedItem == null)
{
e.SuppressKeyPress = e.Handled = true;
((ComboBox)sender).DataSource = accounts
.Where(a => a.Name.Contains(((ComboBox)sender).Text))
.ToList();
((ComboBox)sender).DroppedDown = true;
}
}
}
Anyone can test this easily, its valid for any project.
Upvotes: 0