[v2.9.1] I've fixed a bug where an unsafe cast operation can cause InvalidCastExceptions. From what I can tell, it only seems to happen when there are no columns which can happen sometimes in my threading code that might load rows before columns are loaded, or just because the user happens to mouse over the area a specific times. Since these exceptions happen purely in the OLV Win32 event code, there isn't a (good) way to catch and ignore the exceptions (although you can do it in an CurrentDomainUnhandledException).
The fix for me was to change a casting operation to use the 'as' operator, which returns null instead of an exception being thrown. In OLVListItem.cs#247:
return this.SubItems[index] as OLVListSubItem;
While I personally didn't encounter it here, it's also worth changing Renderers.cs#970 to:
this.SubItem = e.SubItem as OLVListSubItem;
In the Changelog, the comment on 2010.08.18, JPP seems to mention this same issue as being old but fixed. Perhaps it was re-introduced while adding later features, like mouse HitTest which is often mentioned in the trace logs.
So, this only happens when there are no columns? That's an important details I've not heard before. I must admit I've never tried that as a test case.
Thanks for this report. I'll look into it further.
Copied from previous ticket:
An InvalidCastException can occur when processing
OLVListSubItems. Changing most references to the base typeListViewItem.ListViewSubItemand only casting when needed (rare) fixes the issue.This might be isolated to the TreeListView.
Changes Needed:
ObjectListView.LowLevelHitTest, return from GetSubItemObjectListView.UpdateHotRow, return from GetSubItemObjectListView.DrawAllDecorations, foreach loopObjectListView.TriggerFormatRowEvent, foreach loopIn general, it should be impossible for a
ListViewItem.ListViewSubItemto end up within an ObjectListView. So long as developers don't mess with theListViewItemsdirectly, it shouldn't happen.However,
ListViewsare complicated beasts and it could be that there is an exceptional path that I haven't considered (like something odd happens when there are 0 columns).And indeed there is! Using dotPeek I can see in ListViewItem.cs, there is this code:
So, if your
ListViewItemhas no sub-items -- for example, if there were no columns in the control -- this code will helpfully make an empty one for you! Which breaks my pre-conditions :(I will put a fixed version of the code into the repo today.
Thanks for noting that there were possibly no columns in the control when this happened. That was the crucial piece of information I needed that I didn't know from other reports!
Last edit: Phillip Piper 2018-09-01
This is exactly what I expected - some 'magic' generation of items/SubItems, particularly in uncommon scenarios. (This also might help explain why it can happen when there are items in the list - if there's only 1 column, the above auto-generation of subitems would still happen!)
Glad to help! It took quite a bit of digging to narrow down, but since my local copy of the code already had fixes for other occurences, it allowed the no-column observation to come through.
The repo has been updated with the fixed code.
If you can, check it out and see if it fixes the problem for you.
I will try to get my source updated, but it might take some time. I have had a hard time following updates to OLV since it seems like the version is always '2.9.1' while there have indeed been updates. I am not sure if all my local fixes have been applied or not, merging is never fun but I recall them all being very minor so wish me luck!
Hi Guys, i have replaced a plain vanilla ListItemView with this revamped control, everything compiles, but i always get this "cast BrightIdeasSoftware.OLVListItem" error every time.
It is unusable if this is not addressed, because as far as i run my project and form is displayed, an immediate untrappable crash occurs. How is it possible that this bug get unnoticed ? I'm under 2.9.1
Any workaround ? I've havent change a single line of code from my previous ListView, and i just added some SubItems after calling lv .Items.Add()
Last edit: Paolo Marani 2019-11-15
This control is completely different from a normal ListView, are you sure you've changed all the non-object based calls into OLV appropriate calls?
Well, as far as i understand, this component is a subclass/wrapper of a standard listview, so i expect it should work as "drop in" out of the box when extra features are not in use. In my humble opinion, the WinProc should check if you are using standard ListViewItems and keep compatibility with the standard listview as much as possible, and add new features only when switching to OLVListItem. I suggest adding unit testing to ensure legacy addition of item and subitems do work as expected. The WinProc should be bullet proof, otherwise very nasty untrappable exceptions may occur.
Which "appropriate" calls are supposed to be used to avoid such exceptions ? At this time i have no choice then adding source code directly to the project, because nuget package are compiled in release and runtime seem not so reliable as i expected..
Last edit: Paolo Marani 2019-11-15
I apologize i havent properly readed all the documentations, including the fundamental "Getting Started/Unlearn you must" (http://objectlistview.sourceforge.net/cs/gettingStarted.html#gettingstarted) where it is perfectly stated that this is not at all a drop-in replacement for a listview when a lot of boilerplate is already in place. I'll give myself another chance :)
Last edit: Paolo Marani 2019-11-15