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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with coded multi-select List 2

Status
Not open for further replies.

wilfranz

Technical User
Oct 4, 2003
122
US
Hello Friends,

I have a ListBox with MultiSelect set to .T. It works properly with mouse clicks, Shift+Click, and Ctrl+Click. But something weird happens when ALL choices are selected programmatically...

In a CmdButton I am using this code to SelectAll the items...

FOR nI = 1 TO thisform.list1.ListCount
thisform.List1.Selected(nI) = .t.
NEXT

... and this does indeed set all the items to Selected (i.e. they become highlighted). So far so good.

But after this operation, if the mouse clicks on the scroll bar, the entire list de-selects; or if Ctrl+Click is used on any single item of the list (which should normally toggle the Select for only the item pointed), the entire list de-selects except the pointed item which remains selected.

Note that when I manually Select All (i.e. Click at top item, then Shift+Click the bottom item), it works normally in Windows mode. I.e., All are selected, then Ctrl+Click on any single item will toggle the selection.

It's only when I programmatically SelectAll that I have the problem.

What an I missing here?

TIA

wilfranz
 
P.S. Further observation...

Also, if I programmatically pre-select any items from the list with (e.g.)...

thisform.list1.selected(1) = .t.
thisform.list1.Selected(3) = .t.
thisform.list1.Selected(8) = .t.

... the three items are properly selected. But then if the user attempts to manually add any more selections with Ctrl+Click, the first three programmatically selected items de-select.
 
Wilfranz

I have experienced the same problem when programmatically mulitselecting from a list, this problem only seems to occur when I use a rowsourcetype Fields if a rowsourcetype Value is used scrolling a list after programmatically selcting to it the selections remain.

Did you find any solution for this as I must display a cursor to my list and must be able to see my selections.

Cheers
 
Wilfranz

I have experienced the same problem when programmatically mulitselecting from a list, this problem only seems to occur when I use a rowsourcetype Fields if a rowsourcetype Value is used scrolling a list after programmatically selcting to it the selections remain.

Did you find any solution for this as I must display a cursor to my list and must be able to see my selections.

Cheers
 
Hi MForrest,

Sorry, No, I never did find a solution. Have you?

wilfranz
 
I am assuming that the listbox is on a pageframe control, and the listbox itself has no controlsource. Is this correct? If so, this is where the problem is. By moving focus to a different page, you lose the selected values, even though they appear to be selected when you navigate back to the page. It's not the scrolling that is deselecting the values, it's the fact that the control is receiving focus again.

I tried writing code that grabbed the selected values on lostfocus, and selected them again on gotfocus. This didn't work as expected. So the alternative I came up with was to use 2 listboxes instead of one. Put code in the 1st listboxes doubleclick event that adds the selected item to listbox#2. Put code in listbox number 2's doubleclick event that removes the selected value. This way, the wanted items will remain in listbox2 as long as the form is open. You can then loop through listbox2 to get the values you need and do whatever you want through them.

I know this is exactly what you wanted, but in the end you basically have the desired result.

Hope this helps.

-Kevin
 
Hi,

I have been struggling with the same problem you describe above. I have a reasonably elegant approach so I thought I would at least document it here. It is very similar to some of the approaches you have tried so apologies if this doesn't help you.

I am runnin VFP7.0 SP1. The code is tested and works well (you can use CTRL+click to select additional values without losing the defaults)...


1. Add list to form (list1).
2. Set multiSelect to .T. and set no other properties; particularly rowSource & rowSourceType
3. In init() method:

Code:
* Put values in a temporary cursor
SELECT <fieldUWant> AS value FROM <tableUWant> INTO CURSOR __temp

* Add values to the list
SCAN

	thisform.list1.AddItem(__temp.value)
	
ENDSCAN

* Get rid of temp cursor
SELECT __temp
USE

* Build array of default values
PRIVATE values, firstSelected

DIMENSION values(3)

m.values[1] = "A"
m.values[2] = "B"
m.values[3] = "C"

m.firstSelected = -1

FOR i = 1 TO THISFORM.list1.ListCount

	* Find all items to be set as selected
	IF ASCAN(m.values, ALLTRIM(THISFORM.list1.ListItem(i)), -1, -1, -1, 6) > 1
		
		* Set the item as selected
		THISFORM.list1.Selected(i) = .T.
		
		* Store the first selected value
		m.firstSelected = IIF(m.firstSelected = -1, i, m.firstSelected)
		
	ENDIF
	
ENDFOR

* Point us to the highest item selected in the list
IF m.firstSelected != -1 
	thisform.list1.Value = m.firstSelected
ENDIF

Notes:

The "firstSelected" business is simply to put the list back close to the top, rather than leave it at the last default item.

The ASCAN line is just to find if the list item is a default. The extra parameters simply override the system EXACT setting to use EXACT ON.

Hope that is of some help.
 
Believe it or not the problem you are encountering can be easily resolved by set focus to the listbox before running the For loop structure. Cut-N-Paste the code below into a prg and run it from within VFP to see a working example of the difference in behavior.
Code:
PUBLIC oform1

oform1=NEWOBJECT("form1")
oform1.Show
RETURN

DEFINE CLASS form1 AS form


	Top = 0
	Left = 0
	Height = 329
	Width = 375
	DoCreate = .T.
	Caption = "Form1"
	Name = "Form1"


	ADD OBJECT list1 AS listbox WITH ;
		RowSourceType = 2, ;
		RowSource = "crsSource", ;
		Height = 264, ;
		Left = 49, ;
		MultiSelect = .T., ;
		Top = 12, ;
		Width = 277, ;
		Name = "List1"


	ADD OBJECT command1 AS commandbutton WITH ;
		AutoSize = .T., ;
		Top = 288, ;
		Left = 48, ;
		Height = 27, ;
		Width = 132, ;
		Caption = "Set Focus / Select All", ;
		Name = "Command1"


	ADD OBJECT command2 AS commandbutton WITH ;
		AutoSize = .T., ;
		Top = 288, ;
		Left = 228, ;
		Height = 27, ;
		Width = 94, ;
		Caption = "Just Select All", ;
		Name = "Command2"


	PROCEDURE Load
		CREATE CURSOR crsSource (PropName c(30))
		INSERT INTO crsSource (PropName) VALUES ("Bill Smith")
		INSERT INTO crsSource (PropName) VALUES ("Ron Lacey")
		INSERT INTO crsSource (PropName) VALUES ("Ellen Bauken")
		INSERT INTO crsSource (PropName) VALUES ("Todd Tolen")
		INSERT INTO crsSource (PropName) VALUES ("Gary George")
		INSERT INTO crsSource (PropName) VALUES ("Sue Ellen")
		INSERT INTO crsSource (PropName) VALUES ("William Tell")
	ENDPROC


	PROCEDURE command1.Click
		LOCAL lnListCounter
		thisform.List1.setfocus
		FOR lnListCounter = 1 TO thisform.list1.ListCount   
		   thisform.List1.Selected(lnListCounter) = .t.
		NEXT
	ENDPROC


	PROCEDURE command2.Click
		LOCAL lnListCounter
		FOR lnListCounter = 1 TO thisform.list1.ListCount   
		   thisform.List1.Selected(lnListCounter) = .t.
		NEXT
	ENDPROC


ENDDEFINE

boyd.gif

 
Thanks very much Craig. The SetFocus solution is superb. Star submitted with pleasure.

Is there an explanation for why this works? It doesn't seem intuitive.

Bill
 
Thanks for the star. No explanation that I can find or think of. It is obviously by design given the distinct difference in behavior, but why MS felt this was the way to go in this case... I haven't a clue.

boyd.gif

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top