Avatar of rionroc
rionroc
Flag for United States of America asked on

Notice to all .NET Experts who experience imagelist


Notice that imagelist images increasing number of milliseconds during adding images.
Can someone debug this code to make it stable in adding images.

You will notice it in the Form Caption, that there is a time interval between adding images.
Every time you click the button, an interval of milliseconds.

I hope experienced base experts here in EE can solve this issue.

Just change the path before testing, and add images to the imagesfolder a thousand.
''Begin Form1.vb
''===================
Public Class Form1
    'Inherits Form
    Private ThumbEntry() As ListViewItem
    Private stopwatch As New Stopwatch
    Private length As Integer
 
    Private nextdir As String = Nothing
    Private lastdir As String = "D:\All1000mixImages"
    Private retdir As String
 
    Private basePath As IO.DirectoryInfo
    Private DI As IO.DirectoryInfo
 
    Private cachesize As Integer = 0
    Private firstnext As Integer = 0
    Private nextfirst As Integer = 0
 
    Private filename As String
    Private fi As Object
 
    Private Imagelist1 As New ImageList
    Private Imagelist2 As New ImageList
 
    Dim imageStream As System.IO.Stream
    Private istream As ImageListStreamer
    Private h As New Hashtable()
 
    Private Sub ListView1_RetrieveVirtualItem(ByVal sender As Object, ByVal e As RetrieveVirtualItemEventArgs) Handles ListView1.RetrieveVirtualItem
        'Caching is not required but improves performance on large sets.
        'To leave out caching, don't connect the CacheVirtualItems event 
        'and make sure myCache is null.
        'check to see if the requested item is currently in the cache
        If Not (ThumbEntry Is Nothing) Then 'AndAlso e.ItemIndex >= cc AndAlso e.ItemIndex < cc + ThumbEntry.Length Then
            'A cache hit, so get the ListViewItem from the cache instead of making a new one.
            e.Item = ThumbEntry((e.ItemIndex))
 
        Else
            'A cache miss, so create a new ListViewItem and pass it back.
            'Dim x As Integer = 1
            'e.Item = New ListViewItem(x.ToString())
            e.Item = New ListViewItem()
            'ShowImages(lastdir)
        End If
    End Sub
 
    'Manages the cache.  ListView calls this when it might need a 
    'cache refresh.
    Private Sub ListView1_CacheVirtualItems(ByVal sender As Object, ByVal e As CacheVirtualItemsEventArgs) Handles ListView1.CacheVirtualItems
        'We've gotten a request to refresh the cache.
        'First check if it's really neccesary.
        If Not (ThumbEntry Is Nothing) Then 'AndAlso e.StartIndex >= cc AndAlso e.EndIndex <= cc + ThumbEntry.Length Then
            'If the newly requested cache is a subset of the old cache, 
            'no need to rebuild everything, so do nothing.
            Return
        Else
            'Now we need to rebuild the cache.
            'Fill the cache with the appropriate ListViewItems.
            ShowImages(lastdir)
        End If
 
    End Sub
 
    Private Function gti(ByVal filename As String, ByVal width As Integer, ByVal height As Integer) As Bitmap
        Using fs As New IO.FileStream(filename, IO.FileMode.Open, IO.FileAccess.Read)
            Using img As Image = Image.FromStream(fs, True, False)
                Return DirectCast(img.GetThumbnailImage(width, height, Nothing, IntPtr.Zero), Bitmap)
            End Using
        End Using
    End Function
 
    Private Sub ShowImages(ByVal filePath As String)
        Dim p As Integer = 0
        Dim q As Integer = 0
        basePath = New IO.DirectoryInfo(filePath)
        '--------------------
        stopwatch.Reset()
        stopwatch.Start()
        ThumbEntry = New ListViewItem(length) {}
 
        For Each filename In IO.Directory.GetFiles(filePath)
            fi = New IO.FileInfo(filename)
            If fi.Extension.toupper.Equals(".BMP") Or _
               fi.Extension.toupper.Equals(".JPG") Or _
               fi.Extension.toupper.Equals(".GIF") Then
                ThumbEntry(q) = New ListViewItem()
                ThumbEntry(q).Text = fi.Name
 
                h.Add(q, gti(fi.FullName, 100, 80))
 
                ThumbEntry(q).ImageIndex = Imagelist1.Images.Count - 1
 
                q += 1
            End If
            p = CInt(q / length * 100)
            ProgressBar1.Value = p
        Next filename
        ListView1.VirtualListSize = length
 
        stopwatch.Stop()
        Me.Text = "ListView in " + stopwatch.ElapsedMilliseconds.ToString + " mS"
        '-----------------
    End Sub
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Imagelist1 = New ImageList
        'Imagelist2 = New ImageList
 
        Imagelist2.ColorDepth = ColorDepth.Depth16Bit
        Imagelist2.ImageSize = New Size(100, 80)
        ListView1.View = View.LargeIcon
        ListView1.LargeImageList = Imagelist2
 
        Imagelist1.ColorDepth = ColorDepth.Depth16Bit
        Imagelist1.ImageSize = New Size(100, 80)
        ListView1.View = View.LargeIcon
        ListView1.LargeImageList = Imagelist1
 
        Application.DoEvents()
        length = IO.Directory.GetFiles(lastdir, "*.jpg").Length
        length = length + IO.Directory.GetFiles(lastdir, "*.bmp").Length
        length = length + IO.Directory.GetFiles(lastdir, "*.gif").Length
        ListView1.VirtualListSize = length
 
        cachesize = 100
        firstnext = 0
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        '--------------------
        stopwatch.Reset()
        stopwatch.Start()
        'GC.Collect(256)
        'GC.AddMemoryPressure(256)
        'Imagelist2 = New ImageList
        ListView1.BeginUpdate()
If cachesize >= length Then cachesize = length - 1
        For i As Integer = firstnext To cachesize
            Imagelist1.Images.Add(h.Item(i))
            ThumbEntry(i).ImageIndex = Imagelist1.Images.Count - 1
        Next
        ListView1.EndUpdate()
        'GC.WaitForPendingFinalizers()
        'Imagelist1 = Imagelist2
 
        nextfirst = cachesize
        firstnext = nextfirst + 1
        nextfirst = 0
        cachesize = cachesize + 100
 
        stopwatch.Stop()
        Me.Text = "ImageList in " + stopwatch.ElapsedMilliseconds.ToString + " mS"
        '-----------------
    End Sub
 
    Private Sub InitializeComponent()
        Me.ListView1 = New System.Windows.Forms.ListView
        Me.ProgressBar1 = New System.Windows.Forms.ProgressBar
        Me.Button1 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'ListView1
        '
        Me.ListView1.AutoArrange = False
        Me.ListView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None
        Me.ListView1.ImeMode = System.Windows.Forms.ImeMode.Off
        Me.ListView1.Location = New System.Drawing.Point(12, 34)
        Me.ListView1.Name = "ListView1"
        Me.ListView1.ShowGroups = False
        Me.ListView1.Size = New System.Drawing.Size(508, 598)
        Me.ListView1.TabIndex = 0
        Me.ListView1.UseCompatibleStateImageBehavior = False
        Me.ListView1.VirtualMode = True
        '
        'ProgressBar1
        '
        Me.ProgressBar1.Location = New System.Drawing.Point(12, 5)
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(431, 23)
        Me.ProgressBar1.TabIndex = 3
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(449, 5)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(75, 23)
        Me.Button1.TabIndex = 9
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(536, 658)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.ProgressBar1)
        Me.Controls.Add(Me.ListView1)
        Me.Name = "Form1"
        Me.Text = "Form111b"
        Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
        Me.ResumeLayout(False)
 
    End Sub
 
End Class
''End Form1.vb
''===================
 
 
''--------------------------
''Begin Form1.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form
  
    Friend WithEvents ListView1 As System.Windows.Forms.ListView
    Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar
    Friend WithEvents Button1 As System.Windows.Forms.Button
 
End Class
''End Form1.Designer.vb
''-----------------------------

Open in new window

.NET ProgrammingVisual Basic.NET

Avatar of undefined
Last Comment
rionroc

8/22/2022 - Mon
rionroc

ASKER
Is there a .NET expert can debug that code, and make it stable?
Come-on, Please!
That code is running fine, just edit some code to make it stable.
rionroc

ASKER
O, I see, no .NET experts can solve this issue.
Shall I delete this post again?

Why can't anyone try it, if they really think they are one of the best in .NET.

Please try a little help, if I could only change the points to 5000 I will.

:)
rionroc
PaulHews

I don't understand the point of the code in the button, but I can tell you why it gets slower each time you click it.  Each time you click, you add 100 images to the imagelist.  As the number of images increases, the longer it takes to insert a single image.

There is no way to get around the fact that adding more and more images slows down the insertion of images in an image list.  If you tell me the behaviour you are trying to get with your code, I might be able to suggest alternatives.

Also, the hashtable is unnecessary.  You could as easily use an array of type bitmap.

This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
rionroc

ASKER
at Last, a Sage came out.
Thanks Sage PaulHews

The Button is only a test, I want to recycle or reuse the image so that it will not increase load to the memory every time .Add() is issued.
It's suppose to be stable in speed, because every images selected is up to 100 only.


A sort of caching images in different way, and not using the ListView retrieve/cache, only using Virtual to speed up scanned files.

Because the way ListView cache image is slow,  [eq]: when you scroll down,  then images appears(depending in your cachedsize set),  and when you scroll up, it will cache again for previous image cached. (to much delay)

:)
rionroc
ASKER CERTIFIED SOLUTION
PaulHews

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
rionroc

ASKER
Yes!, is there anything you can do to help me?
PaulHews

A file has been uploaded to EE-Stuff.com

Uploaded by : PaulHews
Filename : LIstViewVirtualMode.zip
Size : 77,847 bytes
Comment : Demo of VirtualMode for ListView

You can download this file from https://filedb.experts-exchange.com/incoming/ee-stuff/7553-LIstViewVirtualMode.zip

If other files are available for this question, then they can be accessed from https://filedb.experts-exchange.com/incoming/ee-stuff/7553-LIstViewVirtualMode.ziphttps://filedb.experts-exchange.com/incoming/ee-stuff/7558-LIstViewVirtualMode.zip
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
PaulHews

The point of this demo is to show two different approaches to managing the listview virtualmode.  If you check the "Cache All" checkbox and click "Refresh" it will take a significant amount of time (and memory) to load all the images.    However, the scrolling will be smooth and fast in the listview, because there isn't any disk access.  If you don't check the box and click "Refresh", the listview loads instantly, but scrolling is a little jerky because each time the cache has to be refreshed, you are retrieving images from the disk, which is the slowest part.


rionroc

ASKER
Thanks Sage PaulHews

I'll try if this can help the issue.
I hope it can.
:)
rionroc
rionroc

ASKER
OK Sage PaulHews, you can remove the demo now.  I got it.

I'm very sure, you are a real .NET Sage.

Great is our GOD.
:)
rionroc
Your help has saved me hundreds of hours of internet surfing.
fblack61
rionroc

ASKER
Thanks
rionroc

ASKER
Hey I don't know why is it rated 8.8, But for me its 9.9
:)
rionroc
rionroc

ASKER
Hah!
You are BONO, from the rock band U2.
Is that true that you are bono?

I've heard news that your singing carrier continues to serve the Lord.
Amazing.

When I was still very young, U2 was one of my favorite bands.


Great is our GOD.
:)
rionroc
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
rionroc

ASKER
If you are looking for Bono, I am not him.  LOL, LOL
Anyway Thanks a Lot.
lol, lol,lol, lol,lol, lol,lol, lol,lol, lol,lol, lol,lol, lol,lol, lol,lol
PaulHews

:)  I'm not Bono, but U2 is still one of my favorite bands.  The demo cannot be removed because it is the solution to the question in the database.  Many people use the search capability of EE, so the solution might have use for someone else.

Cheers.
rionroc

ASKER
Hey bono, lol

Can I have another question for you?  I'll post new, if you reply from this.

:)
rionroc
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
rionroc

ASKER
Ops!

Never mine I've solved it.

:)
rionroc