I have a UltraListView with many thousands of items in it. Its a very complicated list and I have it hooked into things like custom search and custom drag drop. So I rather not abandon UltraListView if I can avoid it. But I have hit a tough bottle neck with the UltraListView due to memory.
Each item in my list has a unique image that I generate from disk. In fact it turns out that for my application I need to generate eachi image from a file, one image per file. The files are in an internal format, not a standard image format. An additional constraint is that I want the image to be quite large. The user is often very interested in the details inside the image. So a really small image is not very useful. So each individual image is unique and large in memory.
So I populate the UltraListView with a pool of worker threads that scan the disk and generates all the unique image for each file found.
After about a minute, the list is loaded and then its fast. I can scroll and search and it works fine for my use case.
The down side is that preloading all images takes about 600mb of RAM. So I am getting out of memory exceptions. All those images eat all my spare memory and I dont have enough to run the rest of the app.
I need to stop preloading every single image in the list. I rather only have the images that are actually on screen loaded into RAM. At any given time there are only 50 or so images in view on the list. The rest of the images are all off screen but in memory. I think I need to implement some sort of "In View" cursor and stop preloading the images. I need some set of events that tell me at the UltraListViewItem level who is off screen and who is on screen.
I want an event handler that tells me that a particular UltraListViewItem goes on screen, then I can asychronously be fetched or generate the requisit image for that item. It would be acceptable for the the user to see a small delay as they 'pages in' on a scroll event.
I need another event that tells me a list item is off screen, so I can discard the non visible images and flush it from memory.
At most there only ever be N images loaded into RAM when N is like 3X the number items that can be visible.
So how can I do this? make a "In View" cursor with an UltraListView? Where can I get the on view events at the item level?
Hello,
What you could do in your case is to use Creation Filter. Every time the UltraListView redraws itself the two methods of the filter will be called so you can use it to update the images. If you want to know more about Creation Filter please follow this link:
http://help.infragistics.com/Help/Doc/WinForms/2012.2/CLR4.0/html/Win_Creation_Filter.html
In the AfterCreateChildElements method of the filter you can see which items have UIElement (so they are drawn on the screen) and have no image and add an image to them. Then you could see which items have no UIElement, but have an image and Dispose their image.
I have implemented a sample which demonstrates my suggestion.
Please let me know if you have any additional questions.
opps WS_UltraComboValidation.rar is not a filter sample. Perhapes you intended a different file?
So actually I got something half working. I implemented a
IUIElementDrawFilter
when DrawElement() gets call back by the control I can do the image fetch from disk on demand. So that gives me a very nice 'onScreen' event for each image. The down side of the draw filter approach for what I am doing is that there no clear 'off screen' event so its not obvious when to dispose the un used images with the draw filter. The basic idea is sound though. With the draw filter I only have the images I have actually viewed loaded. So that gets me most of the way there. Can the creation filter work with the draw filter and tell me when a particular images is 'done'? I will look at your sample when its uploaded.