ComboBox open while another control has focus - c#

I have a case where the user is given a ComboBox with potentially a lot of choices in it. Paired with this is a TextBox that filters the items. What I would like to do is open the drop down list when the TextBox has focus--let the user see what the current filter accomplishes as they type it. (This isn't just autocomplete, I'm currently matching the filter text anywhere in the item, I may replace this with a RegEx search down the road.)
It sounds simple enough--drop the box when the TextBox gets focus, close it when it loses focus. It opens--and promptly closes back up. Any good answers?
My Google-Fu must be weak tonight, I can't believe nobody has wanted to do this before yet I find nothing out there. (I have seen a related thing of typing in an open ComboBox to provide suggested options like Google does but my list is required, not merely suggestions.)

You can add on the Focus event of the TextBox code for the ComboBox setting the property
ComboBox.DroppedDown = true;
Than add on the TextChanged event of the TextBox code
ComboBox.SuspentLayout();
//ComboBox.Items add/remove
ComboBox.ResumeLayout();
Don't forget to reset the items when Text is empty.
EDIT:
This seems to work (but you don't get to see the mouse)
string[] items = { "abcd", "abc", "bcd", "cd" };
private void textBox1_TextChanged(object sender, EventArgs e)
{
comboBox1.SuspendLayout();
comboBox1.Items.Clear();
comboBox1.Items.AddRange(items.Where(item => item.ToLower().Contains(textBox1.Text.ToLower())).ToArray());
comboBox1.ResumeLayout();
comboBox1.DroppedDown = true;
}

Related

Custom Control - How to Draw Textbox on combobox

I'm developing Win Form Application
In my UI, I have to make ComboBox which should be dropdown only at first but after selecting any item, it should be partially editable.
E.G.
Options are like,
Item Value - 10
Item Value - 20
Item Value - 30 etc.
Now, if Item Value - 20 is selected, number 20 should be editable (20-29 of course)
But here editing should be allowed only to change numeric value, not Text part.
and also only numeric part should be selected to make it more user friendly.
If there may some internal properties in ComboBox to do so (which I guess will not be the case), it will be straight forward way.
Else to do so, I was thinking of having a TextBox drawn/placed on ComboCox accurately.
In this approach I'm not clear how to put TextBox so accurately that my custom user control looks like single unit and it don't overlap "text" part of combobox ?
I don’t think the combo box control was intended to be used in this way as a simple validated text box seems to be a better control for you and the user if they must enter data. Granted, you could simply add all the numbers you need into the combo box, but the user would have to scroll to the number they wanted. If this list is large then it won’t be very user friendly. The problem with the user typing something into the combo box is a matter of what to do when the user finishes typing. Even with suggestions on, when the user finishes typing something into the combo box, nothing happens until the user presses the Enter key.
If the user typed something that matches one of the items in the list then presses the Enter key, the combo boxes SelectedIndexChanged event will get fired. However, if the user types something that is NOT currently in the items list and presses the Enter key the SelectedIndexChanged event will NOT get fired.
Using the combo box KeyDown event, you could capture the “EnterKey” when the user presses the enter key in the combo box, as this is something the user would do anyway to select an existing item. So when the user types something that already exist in the list and presses the Enter key BOTH SelectedIndexChanged AND KeyDown events get fired in that order. If the user types something that is NOT in the items list, then only the KeyDown event gets fired.
Using the KeyDown event a check is made on what the selected value is. If the item typed by the user is in the items list then we can ignore these as they were handled in the previous call to SelectedIndexChanged. When the user typed something new, obviously you would possibly need to check the range of the values then simply call your method with the users input.
Again this seems hacky and IMHO, a validated text box would be easier on you and simple for the user especially if they have to type it anyway.
List<string> comboData;
public Form1() {
InitializeComponent();
comboData = new List<string>();
for (int i = 1; i < 100; i++) {
comboData.Add(i.ToString());
}
comboBox1.DataSource = comboData;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
MessageBox.Show("selection changed " + comboBox1.Text);
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Enter) {
if (comboData.Contains(comboBox1.Text.ToString())) {
MessageBox.Show("User entered existing data: " + comboBox1.Text);
// selection changed event has already handled this, however
// if the user just pressed "enter" previously
// then selection changed event wont get fired because the selection did not change
}
else {
MessageBox.Show("User entered NEW data: " + comboBox1.Text);
// we have data that is NOT currently in the list
// so selection changed WONT get fired
// need to call your method with user typed value
}
}
}
// make user user only enters numbers
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e) {
if (!Char.IsNumber(e.KeyChar)) {
e.Handled = true;
}
}
Note: I cannot tell what exactly what your combo items list contains. If there is text in the items like “Item Value –”... this seems unnecessary. In the code above I simply used the needed info i.e... the numbers in the combo box items list. Also I used a key press event to filter out unwanted alpha characters.
Hope this helps.

Clear text in Text box on clicking it

I want my TextBox's text which has already product name on it to automatically vanishes when I click on it, and I can enter the text box I want in it.
The product name must be there always while there is no text in the TextBox
I also want that if I click on the TextBox for the second time I don't lose what I've already entered.
Please let me know how can I do it without loosing the data I've entered manually in it and I can get the default text whenever there is nothing entered by myself in the text box.
why use some extra software and not to use your own mind to code? here is the simple code to achieve this task
first use this:
public bool txSearch = false;
then on your text click event code:
private void txtSearch_Click(object sender, EventArgs e)
{
txSearch = true;
if (txtSearch.Text == "Product Name")
{
if (txSearch == true)
{
txtSearch.Text = "";
}
}
}
this will clear your field text box when you click on the text, now to write back the product name when there is nothing in your textbox and you are leaving it do this code on textbox leaving event:
private void txtSearch_Leave(object sender, EventArgs e)
{
if (txtSearch.Text == "") // here you can also use txtSearch.Text != "Poduct Name", but it could affect your search code possibly
{
txtSearch.Text = "Product Name";
}
}
That behavior is known as watermark. You can either :
Use textbox control with watermark from a library such as WPF extended toolkit
Implement it your self using style and attached behavior as demonstrated in this blog post
Do some trick to achieve the same behavior with simpler code, for example as shown in this codeproject post
You should consider using a third party control, there are plenty WatermarkTextbox Controls available. I prefer the one from xceed: http://wpftoolkit.codeplex.com/wikipage?title=WatermarkTextBox
I wrote this behavior by myself some time ago, used an AdornerDecorator to lay over the TextBox, bound the IsFocused Property to my ViewModel and made a flag ShouldShowWatermark in which I bound the Visibility of the AdornerDecorator.
You actually need a watermark for your textbox.
Please look at this answer of Watermark / hint text TextBox in WPF to implement an attached property to a textbox.
This will work:
Go to the "properties" of your textbox. You will see a yellow lightning bolt in the first line tab. There you will find all possible events that can be triggered. Search for "Enter" or "Click" entry, double-click it. There you can put whatever you want (such as textBox1.Clear();)

C# - form combo box snapping closed

I have a winform built in Visual Studio and C#. Up until recently, the combo boxes behaved as expected. However, while adding functionality, I moved all the form elements around and now two of the combo boxes snap closed before an option can be selected (although you can select an item with the scroll wheel or arrow keys). The code in the dropdown event hasn't changed. I'm at a loss - anyone encountered anything like this?
Here's the code of the dropdown event: -
void comboBoxTargetServer_DropDown(object sender, System.EventArgs e)
{
comboBoxTargetServer.Items.Clear();
comboBoxTargetDatabase.Items.Clear();
comboBoxTargetDatabase.Items.Add("");
comboBoxTargetDatabase.Enabled = false;
//ActiveForm.Cursor = Cursors.WaitCursor;
List<string> sqlServers = SQLUtilities.ListSQLServers();
sqlServers.Sort();
foreach (string sqlServer in sqlServers)
{
comboBoxTargetServer.Items.Add(sqlServer);
}
//ActiveForm.Cursor = Cursors.Arrow;
comboBoxTargetDatabase.Enabled = true;
}
Thanks!
You're clearing all of the items once the ComboBox has dropped down. That will empty it, so there's nothing in the DropDown, so the list will disappear. You should pick a different event to fill it. In fact, is the data static within the context of one run of the application? If so, fill the ComboBox on Form Load and leave it at that.

C# autocomplete combobox trigger SelectionChangeCommited

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

How to force control to fire leave event in winforms using c#?

I am pasting text in textbox1.text and I need textbox1 should fire its leave event by itself.
For now I am using this following code. but i will appreciate if anyone can suggest me an elegant or better way:-
private void event()
{
textbox1.Text = SearchedText;
textbox1.Focus();
textbox2.Focus();
}
First I am pasting text, then setting up Focus on the control, then set up focus again on second control. It is firing leave event of textbox1, but any thing better?
Just call the code directly, no need to wait for an event:
private void textBox1_Leave(object sender, EventArgs e) {
mumble();
}
private void someEvent() {
textBox1.Text = SearchedText;
mumble();
}
void mumble() {
// etc...
}
Just calling textBox1_Leave(this, EventArgs.Empty) works fine too.
You should handle the TextChanged or Validated events instead of the Leave event.
To FORCE Leave, Validating and so on Events, no matter what, I've found ONE working solution.
First i tried:
ProcessTabStop(true);
ProcessTabStop(false);
instead of:
textbox1.Focus();
textbox2.Focus();
Problem with the TextBox 1 and 2 Focus() is that its only Active Component that needs Leave, Validating and so on fired, not other Controls, and besides, what if the form is dynamic, you as a programmer not necessarily have any idea what Control you are trying to Leave, that's why i changed Control.Focus() method to ProcessTabStop method above. The problem is then, if only ONE Control has TabStop true, there is no control to go to and back from. So Events are NOT Fired.
Next problem is that i not necessarily Close the Form with the mouse so Focus doesn't change, I use a Key (Ctrl+Enter) to Accept the Form, and then Leave, validating and so on are NOT fired, when i Send Form Close, as Form Close registers weather there are changes or not. But Values are set in Leave on TextBoxes, so I had to find a solution that worked no matter what i did to it. I almost gave up, actually i had a problem report all filled out, when I thought, what if i set ActiveControl to Null and then to the Control it came from. It worked, but had som "Flicker" due to color change on Parent Panel depending on Active or Inactive.
The "Workaround" that works in all cases is:
Control Old = ActiveControl;
// ActiveControl.SuspendLayout();
// ActiveControl.FindForm().SuspendLayout();
ActiveControl = null;
ActiveControl = Old;
// ActiveControl.FindForm().ResumeLayout();
// ActiveControl.ResumeLayout();
That seems to fire Leave, Validating and so on Events, no matter number of Form Controls and TabStopped Controls. You MAY need to SuspendLayout on either ActiveControl, or Form. My Control (Parent Panel) changes color when Active/Inactive, if I do not Suspend Layout on Form, parent panel gets an unwanted "flicker" effect.
Looking at the solution, it is very obvious, now I've found it, but took me half a day to try different things that solved one or another problem, but not all.
I know this a VERY old thread, but one of very few articles I've found on the subject of Forcing Leave Event to be Fired.

Categories

Resources