ComboBox events: SelectedIndexChanged vs. SelectedValueChanged - vb.net

In the context of a data-bound ComboBox whose ValueMember and DisplayMember properties are appropriately set:
Is there a difference between the SelectedIndexChanged and the SelecetedValueChanged events? Are they fired simultaneously when an item is selected from the drop-down list of the ComboBox?

Well, just because your index changes doesn't necessarily mean that your value must change.
This also may not be the most realistic scenario because design-wise this implementation would be bad.
Let's say you are displaying a ComboBox where you are displaying body parts. However, you may be exporting or storing this information in a format mapped to integer values. Therefore, your ComboBox may display "Left Arm" and "Right Arm" which are mapped to a value of 5, which defines (5 = Upper Body) in its mapping. Then, if the user switched "Right Arm" to "Left Arm" there is no value change; however the SelectedIndex has changed.
So I guess it is a case by case basis, but these events surely could function differently depending on the case.

The difference is that SelectedItemChange will be -1 if you edit the combobox ea its not part of the indexed values. However as soon as you start typing in the combobox it will fire value change event.
ea you could use value change to fire events that will reformat text input in a domainupdown control. And if someone edits a domainupdown control and it value becomes -1 you could collect new items to its list (by press of a button and using domainupdown.text property.

Related

How can I set my ComboBox to allow the user to type in the first few characters and then automatically select the item by pressing ENTER?

I have a feeling this is a very simple thing that I'm overlooking.
I have two ComboBoxes that allow users to search for/select the record that they want to view. One is filled with Customer Names and the other is filled with Customer Numbers, so the user can look for a particular record by either selecting the Name or Number.
Each ComboBox is filled by a Data Table returned from a SQL Server database.
Each ComboBox has DropDownStyle set to DropDown, AutoCompleteMode set to SuggestAppend and AutoCompleteSource set to ListItems.
The user can either select by clicking the DropDown arrow and then clicking on the item they was or they can begin by typing and the ComboBox narrows the number of items in the list based on the characters the user is typing.
Using the mouse to click on the item in the list that they want works fine...it fires off a routine to retrieve the selected item from the database.
However, when the user types in the desired selection and presses ENTER, nothing happens. They must click the DropDown arrow and click on the item in order for the program to pull the appropriate record.
How do I get the ComboBox to pull the appropriate record when the user hits enter?
I'm using Visual Basic.
From the sounds of it, you need three events.
You need to use a timer to know when the user has stopped typing. To do that, you need one event would be when that field they're typing in has it's value change (<control's name>.TextChanged). That would start/restart a timer ticking (so that the user has a couple seconds to pause before the next event fires).
The next event would be the Tick event for that timer. That event would stop the timer, and then give focus to the right field so that when the user hits ENTER, they're not hitting ENTER in the field they've been typing in. You'll need to write a function to look up the right item in the ComboBox and call that.
Then you'd have a third event, either KeyPress, KeyDown, or KeyUp on the ComboBox itself. I'd lean towards the KeyUp to avoid issues if the user holds ENTER for whatever reason. That'd be what selects the item.
As a final FYI, I'm assuming you're using Visual Studio to write your code. If not, you should, and if you are/once you are, you can select the field you want to work with in the drop-down at the top left of the editor and then look at the associated events in the top right drop-down.
Thank you to JMichael for getting me on the right track with this one. I'm posting my solution here just in case it helps someone who has a similar question in the future:
The code that I added to the ComboBox's SelectionChangeCommitted event needed also to be added to the ComboBox's KeyUp event:
Private Sub cboPolicySearch_KeyUp(sended as Object, e As KeyEventArgs) Handles cboPolicySearch.KeyUp
If e.KeyCode = Keys.Enter Then
GetSelectedPolicySearchRecord()
e.Handled = True
End If
End Sub 'cboPolicySearch_KeyUp
The GetSelectedPolicySearchRecord() sub contained all of the information I needed to call my SQL Stored Procedure to select the data for the record that the user selected in the ComboBox.
Previously, this was only being called from the ComboBox's "SelectionChangeCommitted" event which is executed when the user clicks the drop down and then clicks a policy number from the drop down list.
I needed to add the same call to the GetSelectedPolicySearchRecord in the ComboBox's "KeyUp" event for when the user presses enter.

Getting value of previous selected item (dropDown)

When a user changes the selected item on a dropdown I need to get the PREVIOUS item selected,
EX:
dropdown items:
1) Questions
2) Jobs
3) Tags
4) Badges
User has #2 Selected and then changes to #4 -- How can I get the value of #2 when they change the selection?
Declare an instance variable in your form (WinForms) or window (WPF).
When a user selects an item:
Do what you want to do.
Save the current item index in the instance variable.
In step 1, you can now access the instance variable to get the previously selected item.
Declare a global variable that will contain the previous value.
When the user changes the selection in the combobox, set the variable to the currently selected value. Allow the selection to be changed. You now will have the previous value.
If you need to have the history of changes, then the global variable would be a collection. Then on changed event, add the current selection to the collection.
If your control is bound to data, there is no need to "Squirrel" the old value away, your data provider usually does this for you.
For example, if you are bound to a DataRow, this code will get the previous value.
? = [Your DataRow].item("[Your column name]",OrigialVersion)
This varies based on your data but ultimately, you could always re-query the database to get the original value as well.
Regardless of what you are bound too, if you ask the datasource for it's value during the Validating event of the control, it will have not changed yet so it will give you the old value, which you can then compare against the current selection.
Lastly, if you are not bound to data, I typically store the old value in the TAG property on the GotFocus event of the control. Then you can compare against that.
Hope this provides some other options that might help you, depending on your case.

Combobox not updating bindtable fields in VB

I have a combobox that is of type dropdown, i.e. allows user to either select something from the list or to type in a new value. Based on this combo value, other values are selected in the form automatically as they are databound.
Customer_ID is the field that needs to be picked or typed in, and based on it Customer first name and second name are updated in the form automatically. This works fine if I pick some value from dropdown, lets say Customer Id = 1111.
Now in place of picking, if i type in this value and press tab, no udpate happens on the Name fields. Please suggest what am I missing here.
I think the best you are going to do with the standard ComboBox is to handle the Leave event, or possibly the TextChanged event. I did some experimenting and typing in a value does not add to the list, it just changes the Text property. It doesn't even change the value of the item you typed over. And, it doesn't fire SelectedItem or IndexChanged events.
So if you handle the Leave event, you have a place to do your lookup when someone tabs off the ComboBox. But the item won't get added to the list.
If you need functionality not provided in the default control, you could redesign your UI with perhaps a TextBox and Button that add an item. Or, you could look for third party implementations of ComboBox controls that would have more functionality.
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
Dim theCB As ComboBox = DirectCast(sender, ComboBox)
DoLookup(theCB.Text)
End Sub

Gray out a form row's (detail's) button conditionally with VBA code

I have a standard form in MS-Access which lists a bunch of orders, and each row contains order no, customer, etc fields + a button to view notes and attached document files.
On request from our customer we should gray out the button btnAnm (or check or uncheck a checkbox) depending on a calculation from two queries to two other tables (a SELECT COUNT WHERE and a check if a text field is empty).
I've tried btnAnm_BeforeUpdate(...) and btnAnm_BeforeRender(...) and put breakpoints in the subs, but none of them trigger. The same if I use the control Ordernr instead of btnAnm.
I'd like a function in the Detail VBA code to be triggered for each "Me." (row) so to speak, and set the row's control's properties in that sub.
What do I do? I've looked at the help file and searched here.
*Edit: So I want to do something that "isn't made to work that way"? Ie. events are not triggered in Details.
As an alternative, could I base the value of a checkbox on each line on a query based on the 'Ordernr' field of the current row and the result of a SELECT COUNT from another table and empty field check?
Do I do this in the query the list is based on, or can I bind the extra checkbox field to a query?
A description of how to do this (combine a COUNT and a WHERE "not empty" to yes/no checkbox value) would be perfectly acceptable, I think! :)*
You cannot do much with an unbound control in a continuous form, anything you do will only apply to the current record. You can use a bound control with a click event so that it acts like a button.
Presumably the related documents have a reference to the order number that appears on your form, which means that you can create a control, let us call it CountOrders, with a ControlSource like so:
=DCount("OrderID","QueryName","OrderID=" & [OrderID])
The control can be hidden, or you can set it up to return true or False for use with a textbox, you can also use it for Conditional Formatting, but sadly, not for command buttons.
Expression Is [CountOrders]>0
You can also hide the contents and add a click event so that is acts in place of the command button. Conditional Formatting will allow you to enable or disable a textbox.
As I understand your question, you have a continuous form with as command button that appears on each row - and you'd like to enable/disable the button conditionally depending on the contents of the row.
Unfortunately you can't do that. It seems that you can't reference the individual command buttons separately.
Having wanted to do something similar in the past I came up with two alternate ways of setting up my interface.
Put a trap into the onClick code for the Button. Which is icky, because it is counter intuitive to the user. But it gets you that functionality now.
Move the command button (and editable fields) up into the form header, and make the rows read only. Your users then interact with the record only in the header, and select the record they want work with in the list below. As I recall this is known a Master-Detail interface.

change the list of combobox A based on the item chosen from combobox B

I am new to vb.net and I am using visual studio 2010. I have two comboboxes on a form, each combobox is set to DropDownList so that a list of items can show in the combobox, but no text is allowed to be entered.
For combobox A, if user chooses item 1, the list of combobox B should be updated accordingly. I think this is quite common on a lot of applications. But I do not know to implement it. I even do not know the keyword to search for the relevant property or event handler.
Thanks a lot!
Take a look at SelectedValueChanged. You can subscrive to this event on your first combobox, then when the event is raised, you can combo2.Items.Clear () the 2nd collection, then add your items.