I'm having problems with the autocomplete property of a combobox. I want to trigger the SelectionChangeCommited event every time I choose an item using the autocomplete but it's not working. The only way the event is triggered is when I use the mouse click and select an option or when the combobox is focused and I use arrow keys on the keyboard. How do I achieve this behaviour using the autocomplete property?
My combo has these properties set:
AutoCompleteMode = SuggestAppend
AutoCompleteSource = ListItems
FormattingEnabled = True
The items in my combo are set with a datasource.
Any ideas?
Thanks
If you mean that you want it to register a change when you start typing:
Call the SelectionChangeCommited event from the TextChanged event.
If you've never done this, the most basic example I could find was on the .net forums here. Granted, the methods shown there are generalities, but is very simple to understand and apply to your code.
EDIT FIXED (as of most recent comment):
Still tie the events together, but instead of using TextChanged, which would occur ever time you type, use the SelectedIndexChanged, which occurs when you use the mouse to select an auto suggested item.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
comboBox1_SelectionChangeCommitted(sender, e);
}
you canuse a trick and call comboBox1_SelectionChangeCommitted
in Validated event
when ever text in combobox changes and user leave the combo box it will be fired
private void comboBox1_Validated(object sender, EventArgs e)
{
comboBox1_SelectionChangeCommitted(sender, e);
}
Related
I have a ComboBox whose DropDownStyle is DropDown, allowing the user to type into it and its AutoCompleteMode is Suggest. The problem is that if the ComboBox is currently open and the user starts typing into it the auxiliary drop-down list appears but clicking on an item from it actually selects the item from the ComboBox's original drop-down list residing under the mouse at the time of click.
I would prefer if while the ComboBox's drop-down list is open the user could not type into it and would like to know if there is a more elegant solution than:
Setting the AutoCompleteMode to None when the ComboBox is open
Possibly changing the DropDownStyle to DropDownList on the OnClick event (haven't tried, but the theory is sound)
Manipulating (or restricting) the entered text while the list is open
Similar
As an option you can handle KeyPress event of the ComboBox and close the dropdown. It keeps the autocomplete menu open, but closes dropdown:
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
this.comboBox1.DroppedDown = false;
}
As another option, you can handle DropDown and DropDownClosed events of the ComboBox and disable autocomplete in DropDown and enable it again in DropDownClosed event:
private void comboBox1_DropDown(object sender, EventArgs e)
{
this.comboBox1.AutoCompleteMode = AutoCompleteMode.None;
}
private void comboBox1_DropDownClosed(object sender, EventArgs e)
{
this.comboBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
}
You can create a new class deriving from ComboBox and override corresponding OnXXXX methods and put the logic there. This way you encapsulate the fix in the control class instead of handling events in your form and will have a reusable bug-free control and a more clean code.
I have a WinForm which contains a multitude of controls interdependent on each other for their visibility and content.
I have a pair of radio buttons, controlling a combobox's (ComboBoxA) enable/disable flag and content. The selection on this combobox controls the visibility of a checkbox. The checking of this checkbox controls another combobox's (ComboBoxB) visibility and content. Business requirements are quite complicated around these controls. As a result, I require the ability to fire of the events programmatically and through user action, doing different things in each case.
In the checkbox's case, I check it programmatically while loading data (if needed), which fires the CheckedChanged event which in turn does additional action controlling ComboBoxB. The code for this is pretty vanilla, nothing special, but my question is more theoretical than practical. Please keep reading.
Due to this requirement, I need a way to distinguish between programmatic checking and user action. I tried using the Click event and CheckedChanged event, setting a flag in the click event, signifying user action. Unfortunately, the CheckedChanged event fires before the Click event, dead-ending this trick.
Now, I tried using the MouseDown event to capture user action. But funnily enough, once the event fires, checkbox remains unchecked and the CheckedChanged event doesnt fire.
Now, I have managed to use a flag in the code to determine programmatic checking and use that to distinguish between the two, but I was curious as to why the MouseDown event didnt allow the checkbox to be checked. Any ideas? I searched online but either I didnt do a thorough job of it, or google is not returning the right results for me. I apologize if anybody is actually able to find a google result for this problem.
It's something else in your code, not the MouseDown event that's preventing the CheckChanged to be fired.
Here is how I know this:
I've added a checkbox and a button to an empty form, and added event handlers to Click on the button, and on the checkbox CheckedChanged, KeyDown and MouseDown events. I've also added to the form a string variable called LastEventRaised, and in the CheckedChanged I've simply shown a MessageBox:
string LastEventRaised = string.Empty;
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
MessageBox.Show("Checked changed " + LastEventRaised);
LastEventRaised = string.Empty;
}
private void checkBox1_KeyDown(object sender, KeyEventArgs e)
{
LastEventRaised = "KeyDown";
}
private void checkBox1_MouseDown(object sender, MouseEventArgs e)
{
LastEventRaised = "MouseDown";
}
private void button1_Click(object sender, EventArgs e)
{
LastEventRaised = "programmatically";
checkBox1.Checked = !checkBox1.Checked;
}
Each time the message box popped up I've got the correct message.
I am developing a windows forms application and load the list from this code:
private void showList()
{
TeamTableAdapter teamAdapter = new TeamTableAdapter();
lstTeamName.DataSource = teamAdapter.GetTeamsActive();
lstTeamName.DisplayMember = "TeamName";
lstTeamName.ValueMember = "TeamID";
}
I want to enable a button if the user selects one of the items. What event should I put the code into. I the following code but the event seems to fire before the user clicks on the list.
private void lstTeamName_Click(object sender, EventArgs e)
{
if (lstTeamName.SelectedIndex > -1)
btnImportXML.Enabled = true;
}
I moved my code to the SelectedIndexChange event but it still fires before the user selects an item and the selectedIndex is 0.
You dont want to bind to the Click event but to the SelectedIndexChanged event. You should be able to accomplish this by simply double clicking on the Control in designer.
I would agree that you don't want to bind to Click as that will likely fire too early.
I recommend you look into the DropDownStyle property. http://msdn.microsoft.com/en-us/library/system.windows.forms.comboboxstyle(v=vs.110).aspx. If you set that to DropDownList then the SelectedItemChanged will fire and SelectedIndex could be > -1
If you leave it as the default DropDown then you may want to use TextChanged and check the Text property.
When I am having a value item selected in my WPf DropDown Combo Box then navigating using keys Left and right arrow keys result in firing of selected changed event for each item.
How to overcome this problem
The most easy and suitable way I found to overcome this problem is as follows:
rather than using SelectedIndexChanged event I used on DropDownClosed event and all code that is wriiten earlier inside selected index changed moved to this event under a if condition that checks whether a item is selected or not. Like this.
private void OnCmbOperatorsListDropDownClosed(object sender, EventArgs e)
{
if (cmbOperatorsList.SelectedIndex != -1)
InsertText(cmbOperatorsList.SelectedValue.ToString());
//Do whatever u want with selected item
}
So in this way when i navigate through Arrow keys SelectedIndexChagned event will not fired or since i haven't used that event so it will not create any problem.
As per my knowledge this is not possible straight away. I could have implemented this in a kind of "selection simulated" manner.
Handle arrow keys on combobox dropdown in PreviewKeyDown event by setting e.Handled = true. So that usual navigation based selection wont happen.
Inthese handlers based on Keys, change the Background and Foreground of the previous or next item from the drop down list so that it will look as if its selected and highlighted.
Then perform selection of the item which curently has the "simulated selection background - foreground" when dropdown closes. After dropdown closure, revert the background and foreground style.
But thats just my way of doing it.
You can use the PreviewKeyDown event like
private void combo_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.Left) || (e.Key.Equals(Key.Right)))
{
((ComboBox)sender).SelectionChanged -= combo_SelectionChanged;
}
}
and if u want to attach that event you can add this PreviewMouseDown event.
This is what i tried and may not be a proper method of doing such cases
i have small problem with autocomplete option in combobox. Everything is working correct, except that i want to work it diffrent :)
When I start typing in combobox, autusuggest working the way i like :
But when i first open combobox, and then start typing i get something like that:
What's more i can't pick item from autosuggest combobox, only from this list under.
AutocompleteMode is SuggestAppend
I'd like to have autosuggest like on the first picture, and in situations like picture 2, this first combobox list should be closed somehow..
I had the same problem and solved it this way:
private void comboBox_DropDown(object sender, EventArgs e)
{
ComboBox cbo = (ComboBox)sender;
cbo.PreviewKeyDown += new PreviewKeyDownEventHandler(comboBox_PreviewKeyDown);
}
private void comboBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
ComboBox cbo = (ComboBox)sender;
cbo.PreviewKeyDown -= comboBox_PreviewKeyDown;
if (cbo.DroppedDown) cbo.Focus();
}
Once the user clicks on the DropDown button PreviewKeyDown event is attached to that ComboBox. When user starts typing, freshly added event is triggered. In that event we check if ComboBox is DroppedDown, if it is, focus that ComboBox. On ComboBox focus DropDown disappeares and that's it.
What about using the DropDown and DropDownClosed events to disable or change the auto-complete mode?
I was having exactly the same problem.
I tried the DropDown and DropDownClosed events to set the AutoCompleteMode property to none and suggest.
In this situation the SelectedIndexChanged event does not get fired after selecting an item with the mouse.
I was using the SelectedValue property in the SelectedIndexChanged event and this property is already changed at the moment the DropDownClosed event is triggered.
In my case I simply called the SelectedIndexChanged method from the DropDownClosed event to solve the problem.
Implement event on ComboBox KeyDown. It should look like this.
void cmbExample_KeyDown(object sender, KeyEventArgs e)
{
if ((sender as ComboBox).DroppedDown)
(sender as ComboBox).DroppedDown = false;
}
Have you tried the other possible values for AutoCompleteMode, which are Append, None, and Suggest? I think that what you are looking for is Suggest instead of AppendSuggest.
Here is some downloadable sample code illustrating the different modes, if you need it.
I also found the default UI implementation distracting as the two dropdowns fight for mouse control.
You want to hide the dropdown list when autocomplete suggestions are shown. There is a windows message that the combobox makes before showing the autocomplete suggestions. I chose to collapse the droplist in response to this message. It requires a small override of the combobox to achieve this:
Public Class Combobox2
Inherits ComboBox
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = 135 AndAlso DroppedDown Then 'WM_GETDLGCODE
DroppedDown = False
End If
MyBase.WndProc(m)
End Sub
End Class
void cmbExample_KeyDown(object sender, KeyEventArgs e)
{
cmbExample.DroppedDown = false;
}