Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Showing an item in a ComboBox after typing some keys 1

Status
Not open for further replies.

SitesMasstec

Programmer
Sep 26, 2010
508
Brasil
Hello colleagues!

My problem is similar I had some years ago, but now I want to improve the solution, if any exists:

Please look at these screens (Design and Run):

TelasBuscaNomes1_g0rwcp.jpg


In the ComboBox space to type, I just want to press one or nome keys in order to highlight the first ocurrence, for example, if I just type BAR, it immediately highlights BARTOL IMPORTAÇÃO E EXPORTAÇÃO LTDA. and I can easily select that name.

I have this code in the Form, Procedure Init:
Code:
SELECT CLIENTES
SET ORDER TO CNOME

thisform.cboName.SetFocus

I have tried some code in the KeyPress event, but I failed. I do not know if this is possible in VFP9.


Thank you,
SitesMasstec
 
Hi,

Did you set the IncrementalSearch property of the combobox to .T.?

You may also have a look look at the help file.

hthMrK
 
Yes, IncrementalSearch is the key. Note that it works best when the Style is set to 2. If the Style is 0, it only works when the list part of the control is actually open.

You might also want to look at the _INCSEEK system variable, which detemines how quickly the user must type the initial letters. In practice, though, it is nearly always OK to keep this at its default value.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Not a result for the third day...

In the Form Form1, Procedure KeyPress, I have:

Code:
LPARAMETERS nKeyCode, nShiftAltCtrl

IF nKeyCode=13 AND nShiftAltCtrl=0 
	EsteCodigo=clientes.ccodi 
	EstaDescri=clientes.cnome
	thisform.Release
ENDIF


In the ComboBox cboName Property IncrementalSearch = .T.- True

In the ComboBox cboName, Procedure KeyPress, I have:
Code:
LPARAMETERS nKeyCode, nShiftAltCtrl

IF ISALPHA(CHR(nKeyCode))
  SELECT CLIENTES
  SET ORDER TO CNOME   && CNOME
  LOCATE FOR UPPER(LEFT(CNOME, 1)) = UPPER(CHR(nKeyCode))
  THIS.SetFocus
ENDIF

When I execute the Form, I type BAR in the ComboBox cboName... it should immediately highlights BARTOL IMPORTAÇÃO E EXPORTAÇÃO LTDA., but nothing happens:
TelasBuscaNomes2_e47629.jpg


I think this a basic function to be used in most applications, so I made a "scan" in many Hentezenwerke books I have about VFP, but I failed to find any example in the last 3 days...


Thank you,
SitesMasstec
 
Reviewing this thread, I implement what Mike said and it worked!
Mike said:
Note that it works best when the Style is set to 2.

(ComboBox cboName, Property: Style = 2-Dropdown List)

After the change above, when I execute the Form, I typed BAR in the ComboBox cboName and it highlighted BARTOL IMPORTAÇÃO E EXPORTAÇÃO LTDA.:
TelasBuscaNomes3_y1wr2y.jpg


The ideal would be to present like in this image (I clicked the down key beside the result BARTOL...), but maybe I am willing too much:
TelasBuscaNomes4_bbbmpv.jpg



Thank you,
SitesMasstec
 
Hi,

Just hit SPACE on your keyboard after you entered the item to search for.

hth

MarK
 
Are you asking for a way to programmatically open the drop-down part of the list? If so, the usual way of doing that would be [tt]KEYBOARD "{ALT+DNARROW"}[/tt]. But I can't see how that would work in this case, because there would be no opportunity for you to do that. You want the drop-down to open as soon as the user has finished typing. But there is no way for your program to know when that happens.

Apologies if I have misunderstood what you are asking.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I think what you mean is you want a spearation of what was typed and highlighting in the dropdown list, so if multiple items are candidates that can be seen.

Well, as Mike said incremental search is most simple with Style 2, but the help on IncremetalSearch tells you what else works, too:
help incrementalsearch said:
A combo box with the Style property set to 0 (Dropdown Combo) will only show incremental searching in the text box if the drop-down list is shown. With the Style property set to 2 (Dropdown List), incremental searching will show in the text box, regardless of whether the drop-down list is shown.
Mike has now told you how to drop down the list. So you can make use of that.

But remove your code from the combobox keypress, though. You're lucky the incremental search still also works, but you're sabotaging the built in feature when you program on top of it something that locates records. If you want incrementalsearch to work, you want an inbuild feature to work and you sabotage it by doing your own code doing LOCATEs in the same workarea.

Chriss
 
MarK:
Yes, it is good, but the ideal would be when the first letter is entered the list opens highlighting the first occurance of that first letter in the names (I just clicked the down arrow to show what I would like to happen when I press the first letter of any group of letters to search in the list, for example, BAR):
TelasBuscaNomes4_vp7eyn.jpg


Mike:
When Init the Form, the focus is set to ComboBox. Well, in the ComboBox, Procedure GotFocus, I have:
KEYBOARD "{ALT+DOWNARROW}"

So, I understand that when the ComboBox got focus, the list of names should be opened, but this doesn't happen! But if, in my keyboard, I press Alt and the down arrow the list of names opens! But the list closes as soon as I type any letter.

When executing, I got the error Key label 'ALT+DOWNARROW' is invalid.

Chris:
On, yes, I took out the LOCATEs, it is not necessary.



Thank you,
SitesMasstec
 
It's not only the locate that's unnecessary, remove all code from the keypress event.

Also, Keyboard and Key label are both commands, but Key Label doesn't do the same, you don't need KEY LABEL.

You're missing the exactly recommended way to write the key combination for the KEYBOARD command. It's DNARROW, not DOWNARROW.

Code:
Keyboard '{ALT+DNARROW}'
Just copy that code for Gotfocus, SitesMasstec, select it, CTRL+C for copy and CTRL+V for pasting it into the VFP editor. Don't type it. And if you would and pay attention to the intellisense choices offered, you'd allso see confirmed that it's DNARROW, not DOWNARROW:
Dnarrow_jbqbez.png


There's still some things which let me prefer the DropdownList style instead of the combo:

1. Typing incremental to get to the item you want causes multiple InteractiveChange events. That's not the worst, because that'll also happen in Style=2.
2. Style 0 allows typing in something intop the textbox portion that's not found in the list.

You can combine Style=2 with the Keyboard '{ALT+DNARROW}' and get the best of both modes.

To finally have an event that tells you the actual choice made by the user is with the Valid event, even better with SET CONFIRM ON where you need an explicit ENTER/RETURN to confirm the choice. Don't forget you SET CONFIRM ON on GotFocus, too and turn it off again in LostFocus or Valid

Chriss
 
Great, Chris!
Now I have it: I corrected the DOWNARROW to DNARROW, and took out the code from the KeyPress event:

I just run the form and have not pressed anything before typing BAR to make the selection!

TelasBuscaNomes5_wbjzij.jpg


To have the selection the user makes, I have this code in the KeyPress event in the ComboBox:

Code:
EstaDescri=this.Value

Even without the SET CONFIRM ON at GotFocus and SET CONFIRM OFF at LostFocus event, it behaves as it has these commands (SET CONFIRM ON/OFF). Anyway I'll use these commands to be sure.


Thank you,
SitesMasstec
 
I would recommend to really have no code in keypress.

Copying This.Value into a variable or field with every keypress you're doing a lot of assignments that are irrelevant, because the active item changes often and you never know whether it's the item the user actually wants to pick. The value property stores its value, all the time, and its value is most recent anytime you access it. So there is no reason to copy it everytime a key is pressed.

Nevertheless the worry I had is that you do a lot of things like adding records, setting focus to other elements, etc. when an item is picked. Such things should absolutely wait until the user confirms his selection. And that's clearly that way in the Valid event, especially with SET CONFIRM ON while the combobox has focus.

And not only when CONFIRM is ON, the Valid event is where you (your code) decides whether the Value of a control is accepted and valid, or whether you keep focus there and force correction. It has it's pros and cons to do that, but it's clearly the only moment the value of the control is relevant as it stays that way until the control is used again to change it. When you confirm the validity by returning .T. there (or having no RETURN stateement at all) then the value is also what's stored back into the controlsource, of that's set. So Valid is the moment of truth.

Chriss
 
Hi

Yes, it is good, but the ideal would be when the first letter is entered the list opens highlighting the first occurrence of that first letter

Well, just hit the SPACE bar after you typed the first letter

hth

MarK
 
True, MarK, and the user can even start by pressing SPACE as first act after tabbibng to the combobox, drop down the list and do incremental search from there, just as ALT+DNARROW invoked by focussing the control does now without the user involvement. You could also program KEYBOARD ' ' in the gotfocus.

In the end it's also a matter of taste, I would think something's wrong when just tabbing to a combobox drops down its item list, because many times I will just tab to something else and going through controls I don't intend to use and that list would flash shortly and irritate me. But you can tab through.

I think it's what sticks in some Foxers doing lots of legacy applications which had all those single READS using one control after the other in a guided sequence. It's not what Windows aims for which instead enables parallel usage and access in any order you want to use controls.

If you want to enforce a specific order of usage of controls, then disable all but the first control you want to force the user to use, then enable the next, etc. That's what I usually recommend to those wanting enforced order of usage of controls. You're not understnding the freedom you take away from yourself and from the user, though.

Chriss
 
What I do not understand is that as KeyPress is an Event that was just occured, why is it not named KeyPressed? (Even if the verb 'to press' were an irregular verb, let's say it in the past tense were 'press', this Event should be named KeyPressed, for the sake of clarity).

As GotFocus is a (just) past Event.

Maybe I am missing something in my assertion above, as I am not an expert in VFP.


Thank you,
SitesMasstec
 
Well, if you expect consistency with the names of events vs methods, then you did not find the only inconsistency.

Just open up the methods tab of the property window while you have a form designer up. You'll all Methods and Events (which is just another example of an inconsistency, Methods and Events are not separated).

Click is also not called Clicked, MiddleClick is not called MiddleMouseButtonClicked. Should I even go on?

You know which is a Method and which is an event by the two different Icons. All events happen by some causal event, and KeyPress happens when a key was pressed, indeed. What things are called is not our choice, is it? All you need to know is the differentiation of events and methods.

In the case where I asked you to not use the KeyPress event to set EstaDescri=this.Value this is not because it doesn't work, but the other thing to know about events is when they happen, why they happen, and which event is best for which use case. It's enough to record the last value when the Valid event happens, there's no need to set EstaDescri 5, 10, 100 times before the user makes the actual pick and then leaves the combobox, that's why I asked to do that. Not using the appropriate event for what you need is pointing out not knowing better, or worse - not caring, or the worst - just guessing. If you only care that something works and not why, you can continue that way, but knowledge is key to doing something right.

Chriss
 
Touché!, Cris.

And I moved the EstaDescri=this.Value to the LostFocus of the ComboBox, I understand it is better. I do not understand why to put this command in the Valid event, instead of LostFocus.



Thank you,
SitesMasstec
 
Maybe a code example will open your eyes:

Code:
Public goKeypressform, gcTextboxvalue
goKeypressform = CreateObject("keypressform")
goKeypressform.Show()

Define Class keypressform as Form
   Top = 2
   Left = 100
   Add Object text1 as textbox
   
   Procedure text1.Keypress()
      LPARAMETERS nKeyCode, nShiftAltCtrl
      gcTextboxvalue = This.Value
      Activate Screen
      ? gcTextboxvalue
   EndProc
EndDefine
Type abc, whatever.
Keypress events will happen and set gcTextboxvalue = This.Value, then print that on the IDE screen.

Why is the value shown on the VFP IDE screen always one behind what's displayed in the form textbox directly?

Is it a good event to capture the textbox value, therefore?

The answers are in the documentation of the Keypress event telling when it is invoked and what it's for.

Chriss

PS: Why the vlaid event. Well, please just read up on it, read what I already told you. Lostfocus is okayish, but valid is the event where the control value is stored into the controlsource. And as it's good for that, which is what is stored into a DBF file and persisted, it's also good for you to know what the final value is.

LostFocus is happening when the control lost focus, it happens just after valid, the value still is the same and it works, but the intention of the lostfocus event is to react to the loss of the focus, no mopre, no less.
 
Yes, Chris, good example, thanks. I tested your program and realized why not to store variables in the KeyPress event.

As I had told in my previous post, I stored the variable in the LostFocus event of the ComboBox.


Thank you,
SitesMasstec
 
I already reacted to that and explained why Valöid is the right event. I ssume you're still in the prototyping phase? Besides the fact that I would't call something prototyping that already implements complete behaviour of the IDE, that's your decision.

If you later use controlsources to store values including which item a user picked in this combobox, that storage into the backend tables will happen in the valid event, not löostfocus. You're not totally off with the Lostfocus as it's the last event in the cycle of a control being used from When (yes, When, not GotFocus) to LostFocus, but it's not the event VFP itself uses for data persisting and so you should use the same as VFP uses when using controlsources, simple enough reason.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top