How to Build a Custom Combo Box

ID: Q155013

3.00 3.00b WINDOWS kbprg kbhowto
The information in this article applies to:


SUMMARY

When using a large table or cursor (over 500 records) as the RowSource for a Combo Box, you may start to see a slow down in the Combo Box performance. This article shows how to create a control that has the basic Combo Box functionality but does not have the same performance slow down that the standard Combo Box has when working with a large table.


MORE INFORMATION

The fastest control for working with a large number of records is the Grid. However, there are times when there is not enough space on a form for a grid or when the developer needs the functionality of a Combo Box but without the performance overhead that the standard Combo Box has. The following example shows how to create a custom Combo Box using a Grid, Text Box, and Command Button. If you are not familiar with creating or using visual classes, please see chapter 10 of the Microsoft Visual FoxPro Developer's Guide.

Step-by-Step Example



  1. Create a new class named NewPopup based on a Container, and save it in Mylib.


  2. Add the following new properties and methods to the NewPopup container: cSearchString as a Property tOutTime as a Property Pop as a Method Search as a Method


  3. Set the following properties for the NewPopup container: Width = 128 Height = 185 BackStyle = 0 BorderWidth = 0 tOutTime = .NULL.


  4. Add a Text Box to the container and set the following properties: Height = 26 Left = 2 ReadOnly = .T. && If you want to be able to edit the data in ** the text box leave this property set to .F. Top = 2 Width = 111


  5. Enter the following code in the KeyPress Event for Text1: IF nKeyCode = 160 This.Parent.Command1.Click() ** Makes the grid appear when you press the ALT+DOWNARROW key ENDIF


  6. Add a Command Button to the container and set the following properties: Top = 2 Left = 112 Height = 26 Width = 13 FontBold = .F. FontName = Wingdings FontSize = 6 Caption = ALT + 0234 ** When you hold down the ALT key and press the NUMBER keys, it ** inserts a down arrow character for the Caption


  7. Enter the following code in the Click Event for Command1: This.Parent.Grid1.Visible = .T. && Make the Grid visible This.Parent.Zorder(0) ** Places the container in front of other objects This.Parent.Grid1.Column1.Text1.SetFocus IF !ISNULL(This.Parent.tOutTime) KEYBOARD '{Enter}' ** Forces the Grid to Activate ** Without this, the grid would not work properly when you ** enter it the second time. ENDIF


  8. Add a Grid to the container and set the following properties: ColumnCount = 1 DeleteMark = .F. GridLines = 0 GridLineWidth = 0 HeaderHeight = 0 Height = 156 Left = 2 MousePointer = 1 ReadOnly = .F. RecordMark = .F. ScrollBars = 2 Top = 27 Visible = .F. Width = 123


  9. Enter the following code in the AfterRowColChange Event of Grid1: This.Parent.Text1.Value = This.Column1.Text1.Value


  10. Set the following properties for Column1 in Grid1: Width = 124 Sparse = .F.


  11. Set the following properties for Text1 in Column1 of Grid1: BorderStyle = 0 Format = K HideSelection = .F. MousePointer = 1 SpecialEffect = 1


  12. Enter the following code in the Click Event of Text1 in Column1 of Grid1: This.Parent.Parent.Parent.Pop()


  13. Enter the following code in the KeyPress Event of Text1 in Column1 of Grid1: IF nKeyCode = 13 && Then hit the ENTER key This.Parent.Parent.Parent.Pop() ENDIF IF (nKeyCode > 48 AND nKeyCode < 58) OR ; (nKeyCode > 64 AND nKeyCode < 123) ** Calls the search method if you hit a letter or numeric key This.Parent.Parent.Parent.Search(nKeyCode) ENDIF


  14. Enter the following code in the GotFocus Event of the NewPopup Container: SET BELL OFF


  15. Enter the following code in the Init Event of the NewPopUp Container: This.Grid1.HeaderHeight = 0 ** When you modify an instance of the class in a Form and modify ** some of the grid setting, it will change the HeaderHeight ** property back to a default size. This line of code will set the ** HeaderHeight back to 0 at run time This.Zorder(1) ** Moves the container behind any controls that it may be on top of nFieldlen = FSIZE(This.Grid1.Column1.ControlSource) ** resize the grid based on the field size and font IF This.Width < (nFieldlen * ; FONTMETRIC(6,This.Grid1.FontName,This.Grid1.FontSize,"B"))+12 This.Width = (nFieldlen * ; FONTMETRIC(6,This.Grid1.FontName,This.Grid1.FontSize,"B"))+12 This.Grid1.Width = (nFieldlen * ; FONTMETRIC(6,This.Grid1.FontName,This.Grid1.FontSize,"B"))+10 This.Grid1.Column1.Width = (nFieldlen * ; FONTMETRIC(6,This.Grid1.FontName,This.Grid1.FontSize,"B")) ENDIF


  16. Enter the following code in the LostFocus Event of the NewPopUp Container: SET BELL ON This.Grid1.Visible = .F. This.ZOrder(1) ** Moves the container behind any object it is over


  17. Enter the following code in the Pop Method of the NewPopUp Container: This.Text1.SetFocus This.Grid1.Visible = .F. This.ZOrder(1) ** Moves the container behind any object it is over


  18. Enter the following code in the Search Method of the NewPopUp Container: **Does an incremental search of the table in the grid LPARAMETERS nKeyPress cField = This.Grid1.Column1.ControlSource nRecord=RECNO() tInTime = DateTime() IF !ISNULL(This.tOutTime) IF (tInTime - This.tOutTime)<= 1 This.cSearchString = This.cSearchString + CHR(nKeyPress) LOCATE FOR UPPER(LEFT(&cField,LEN(This.cSearchString))) = ; UPPER(This.cSearchString) ELSE This.cSearchString="" This.cSearchString = CHR(nKeyPress) LOCATE FOR UPPER(LEFT(&cField,1)) = UPPER(This.cSearchString) ENDIF IF FOUND() This.Grid1.Refresh() ELSE GO nRecord This.Grid1.Refresh() ENDIF ELSE This.cSearchString="" This.cSearchString = CHR(nKeyPress) LOCATE FOR UPPER(LEFT(&cField,1)) = UPPER(This.cSearchString) IF FOUND() This.Grid1.Refresh() ELSE GO nRecord This.Grid1.Refresh() ENDIF ENDIF This.tOutTime = DateTime()


  19. Save and close the class.


  20. Create a form and add the NewPopUp container to the form.


  21. Set the RowSource of the Grid1 in the NewPopUp container to the table of your choice.


  22. Set the ControlSource of Column1 of Grid1 in the NewPopUp container.


  23. Save and run the Form. Click the Command Button to display the Grid, and then type the first letter of something you wish to find. Make a selection by either clicking on your choice or using the ARROW key to highlight your choice and then pressing the ENTER key. You will see the Grid disappear and the value of your choice appear in the text box.


Additional query words: kbdsd VFoxWin combobox listbox performance slow


Keywords          : kbVFp300 kbVFp300b kbVFp600 FxprgClassoop 
Version           : 3.00 3.00b
Platform          : WINDOWS 
Issue type        : 

Last Reviewed: January 20, 1999