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 SubEnd 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.ButtonEnd Class''End Form1.Designer.vb''-----------------------------
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.
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)
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.
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.
Come-on, Please!
That code is running fine, just edit some code to make it stable.