Jump to content
Bart Kindt

Virtual Listview does not work because 'un-select' is not reported

Recommended Posts

I have a unit which tries to use the TListView in Virtual mode, by setting OwnerData to true.

Theroretically all this should simply work, as long as I monitor the OnData, OnSelectItem, OnDataStateChange and possibly OnChange.

But what happens, it that all 'OnSelect's are reported by Windows, but NOT all 'unSelect's.

As a result, my VirtualItemList end up with more and more Selected Items, while in reality, there is (for example) only 1 Selected Item in the ListView.

Below is an (Log) example of what happens:

= I click on item 0:

OnSelectItem: Item not assigned!
OnChange: Index=0 Virtual Count=3001 Item=Caption 0  Selected=TRUE
OnSelectItem: Item=Caption 0  Item.Selected=TRUE  Selected=TRUE

= I now shift-click on Item3, to multi-select all 4 Items:

VirtualItemList.OnSelectItem: Item not assigned!
*** OnDataStateChange: Start=0  End=3
*** OnDataStateChange: 0 Item: Caption 0  Selected=TRUE
*** OnDataStateChange: 1 Item: Caption 1  Selected=TRUE
*** OnDataStateChange: Changing VirtualItem Caption 1 to TRUE
*** OnDataStateChange: 2 Item: Caption 2  Selected=TRUE
*** OnDataStateChange: Changing VirtualItem Caption 2 to TRUE
*** OnDataStateChange: 3 Item: Caption 3  Selected=TRUE
*** OnDataStateChange: Changing VirtualItem Caption 3 to TRUE
OnChange: Index=0 Virtual Count=3001 Item=Caption 0  Selected=TRUE
OnChange: Index=3 Virtual Count=3001 Item=Caption 3  Selected=TRUE

MouseUp: Base Selcount=4 Virtual=4 REAL=4

NOTE:
- OnSelectItem is NOT called during 'Shift-Click' for the Selected items. 
- I now must use OnDataStateChange to Select these. 
- OnChange is ONLY called for Index 0 and 3. Not for the ones in between.

= I now click on Item 4. (This should UN-select all other Items. It does do so on the screen...)

OnSelectItem: Item not assigned!
OnChange: Index=3 Virtual Count=3001 Item=Caption 3  Selected=FALSE
*** OnChange: Caption 3 has changed to: FALSE
OnChange: Index=4 Virtual Count=3001 Item=Caption 4  Selected=TRUE
*** OnChange: Caption 4 has changed to: TRUE
OnSelectItem: Item=Caption 4  Item.Selected=TRUE  Selected=TRUE

MouseUp: Base Selcount=1 Virtual=1 REAL=4

NOTE: 
- The OnChange only reported UNSelect for Item 3, and the Select for Item 4, but there is no event anywhere for Item 0, 1 and 3.
- I now have FOUR Selected items in my Virtual List (The SelCount is hard overwritten from the ListView Selcount)
- OnDataStateChange is NEVER called to report all the UN-Selects.

The entire Test program source code can be downloaded here (200k):

https://sartrack.nz/temp/VirtualListViewTest.zip

 

I really wonder if it possible at all to do this, as this seems to be a Windows issue.

Using Windows 10, Delphi 11.

 

Share this post


Link to post

Didn't you ask this on SO recently, and get an answer? Could you link that question, which is always good practise when cross-posting.

Share this post


Link to post

In my virtual list view I'm getting OnSelectItem fired whenever the selection changes. However, the Item and Selected arguments don't tell you everything that has happened. You just need to run through the list and check Selected on each item again.

Share this post


Link to post
6 minutes ago, David Heffernan said:

In my virtual list view I'm getting OnSelectItem fired whenever the selection changes.

Things are a bit more difficult when MultiSelect is allowed. That makes it even more necessary to check the Selected list for synching the ListView state with the external one.

Share this post


Link to post
44 minutes ago, Uwe Raabe said:

Things are a bit more difficult when MultiSelect is allowed. That makes it even more necessary to check the Selected list for synching the ListView state with the external one.

That's the scenario I have, with multi select enabled. And yes I walk the entire list checking selected state for each item. 

Share this post


Link to post

AFAIR you have to listen for state change event and analyze item state.

IMHO Listview is an awkward and slow piece of crap. I advice to avoid it where possible

Share this post


Link to post
1 hour ago, David Heffernan said:

That's the scenario I have, with multi select enabled. And yes I walk the entire list checking selected state for each item. 

I wonder if OnSelectItem alone works when selection is done by Ctrl-Click or Ctrl-<cursor keys>. In one of my applications I had to wire OnDataStateChange, too. Without that I missed some notifications to react on selection changes.

Share this post


Link to post
10 hours ago, Fr0sT.Brutal said:

AFAIR you have to listen for state change event and analyze item state.

IMHO Listview is an awkward and slow piece of crap. I advice to avoid it where possible

It's not slow in virtual mode. 

 

2 hours ago, Bart Kindt said:

Fr0sT.Brutal: So what alternative you have for the TListView?

 

VirtualTreeView is the usual alternative. 

Share this post


Link to post

I have now changed the way it works, as basically the whole system does not work at all as claimed.

- OnSelectItem is only called during a single Select. It is NOT called during any UN-Select

- OnSelectItem is NOT called during a multi-Select (Shift-Click, CtRl-Click).

-- In this case, OnDataStateChange is called for the range of Selected Items (with a proper Begin and End count).

- OnDataStateChange  is NOT called when a range of Items is UN-Selected.

The final result of this is, that the whole system is basically useless in its behavior.

 

As mentioned by other posters, the only way to use it is:

- On every OnSelectItem , completely Clear the entire milion+ Virtual listview, and then go through the *entire* milion+ TListViews and reset all Select's and UN-Select's.

- On every OnDataStateChange , then process the selected Range (Begin to End) but ignoring the "OldState, NewState: TItemStates" which do not seem to have any effect.

 

I can only hope that OnDataStateChange fully works in this case, because if it also cannot be trusted, then I would have to do a complete Clear and complete reload every time this is called... and it *is* called for example 100 times in a row if you select 100 Items with Shift-Click.

 

I find all this quite unbelievable, considering it must have been like this for 25+ years if not more.  And there is no reference about this bad behaviour in the Dephi or Windows documentation.

 

Bart

 

Share this post


Link to post
1 hour ago, Bart Kindt said:

I have now changed the way it works, as basically the whole system does not work at all as claimed.

- OnSelectItem is only called during a single Select. It is NOT called during any UN-Select

- OnSelectItem is NOT called during a multi-Select (Shift-Click, CtRl-Click).

FWIW this doesn't match what I see in my list 

Share this post


Link to post

David: Are you prepared to email me (part of) your version of the 'Vitual List'?

Also: What version of Windows and Delphi do you use?

 

Share this post


Link to post
11 hours ago, Bart Kindt said:

So what alternative you have for the TListView?

VirtualTreeView is worth trying

Share this post


Link to post

I think I tried this before, but I need a system which looks line ListView.

I will have a look at it.

But it must be free because my SARTrack Search and Rescue software system is free. 

Share this post


Link to post
49 minutes ago, Bart Kindt said:

But it must be free because my SARTrack Search and Rescue software system is free. 

See GetIt

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×