2016-04-12 27 views
0

için yanlış görüntüler Ben şöyle bir dizinin tüm öğeleri listeleyen bir liste görünümü:ListView her öğe

file system

:

card gallery

Ama bu resimde görebileceğiniz gibi

Sırayla değil, bir görüntü metni tamamen atlandı, ancak görüntünün kendisi hala sırada. o yaklaşık yarım başlayarak listenin altındaki alır

Ama onlar tamamen bu örnekte olduğu gibi, karışık olma başlatmak: Bir görüntüyü tıklandığında doğru önizleme gösterir

Image 3

Sağ taraftaki görüntü. Bunun görüntülerin büyük miktarda için muazzam yükleme süreleri vardı BackgroundWorker eklenen Önce yüzden,

Dim imgList As New ImageList 
    Dim imgSize As New Size 
    Dim count As Integer = 0 
    Dim imgFilename As String 

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
     'Dim imlTemp As New ImageList 
     Dim dirFiles() As String = IO.Directory.GetFiles(My.Settings.GalleryLocation) 

     'Dim item As New ListViewItem 
     For Each dirFile As String In dirFiles 
      imgFileName = IO.Path.GetFileName(dirFile) 
      Dim img As New System.Drawing.Bitmap(dirFile) 
      Dim imgImage As Image = Image.FromFile(dirFile) 
      'Dim imgHeight As Integer 
      'imgHeight = imgImage.Height 
      imgSize.Width = 120 
      imgSize.Height = 174 
      Threading.Thread.Sleep(10) 
      BackgroundWorker1.ReportProgress(100/((dirFiles.Count + 1) - count), img) 
     Next 
    End Sub 

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
     ListView1.SmallImageList = imgList 
     ListView1.LargeImageList = imgList 
     imgList.ImageSize = imgSize 
     imgList.ColorDepth = ColorDepth.Depth32Bit 

     ListView1.Items.Add(imgFilename, count) 
     imgList.Images.Add(e.UserState.Clone) 
     count += 1 
     'ListView1.EnsureVisible(ListView1.Items.Count - 1) 
    End Sub 

:

image 4

Bu

tüm görüntülerde ben yüklemek için kullanıyorum kodudur Async çalışmasının yapılmasına izin vermek için arka plan çalışmasını yapacağımı düşündüm. Bununla birlikte, görevin başlangıcında bir şey tamamen yanlış gidiyor ve liste boyunca birden çok kez parçalı bir şekilde görünüyor, burada Resim 3'te gösterildiği gibi tamamen dağınık.

Neyin yanlış gittiğine dair herhangi bir fikri olan var mı? Ne yapmayı planladığıma çözümler?

cevap

1

ReportProgress() engellemediğinden (bildiğim kadarıyla), dosyaların UI'nin güncelleştirebileceğinden daha hızlı olsa da yinelenme olasılığı vardır.

Bu senkronizasyonu korumak için, güncellemek istediğiniz her şeyi tutan ve bunu ReportProgress() yöntemine ileten özel bir sınıf oluşturmalısınız (hatta bazı adımları otomatik hale getirerek). Örneğin

:

Public Class GalleryImage 
    Public Property FullPath As String 
    Public Property FileName As String 
    Public Property [Image] As Image 


    Public Sub New(ByVal File As String) 
     Me.Image = Image.FromFile(File) 'Get the image. 
     Me.FullPath = File 'Save the full path of the image. 
     Me.FileName = Path.GetFileName(File) 'Get the file name. 
    End Sub 
End Class 

(Eğer dosya adı değil, uzatma istiyorsanız Ayrıca, Path.GetFileNameWithoutExtension() kullanabilirsiniz) kodunuzu Şimdi


. Her şeyden önce,10 değişkeni, ListView1.Items.Count veya imgList.Images.Count tarafından değiştirilebileceği için gerçekten gerekli değildir. İkinci olarak, imgSize değişkenini veya ListView'un Small-/LargeImageList özelliklerini sürekli olarak ayarlamaya devam etmemelisiniz. Bunu yapmak tamamen gereksiz ve işleri yavaşlatır. ListView için sadece bir kez görüntü listesini ayarlamak ve imgSize değişken için böyle yapabilirsiniz:

Dim ReadOnly imgSize As New Size(120, 174) 

değişken ReadOnly ne gibi sesler yapar yapma; ondan okuyabilir, ancak değiştiremezsiniz.

Şimdi backgroundworker en For Each döngü içinde başlayacağız bu şeyleri düzeltmek için:

For Each dirFile As String In dirFiles 
    Threading.Thread.Sleep(10) 'You don't need this Sleep if you don't want to. 

    'Report the progress, declare an in-line version of our class and send it with. 
    BackgroundWorker1.ReportProgress(100/((dirFiles.Count + 1) - ListView1.Items.Count), New GalleryImage(dirFile)) 'A new GalleryImage is created. The property setting is handled by the class itself. 
Next 

sen şimdi oldukça fazla aşağı kod daraltmıştır Gördüğünüz gibi.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    'In here we do all the standard settings and initializations. 
    ListView1.SmallImageList = imgList 
    ListView1.LargeImageList = imgList 
    imgList.ImageSize = imgSize 
    imgList.ColorDepth = ColorDepth.Depth32Bit 
End Sub 
: son olarak, malzeme başlatma ve ilk ayar örneğin içinde Form Load olay yapılmalıdır

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
    Dim img As GalleryImage = e.UserState 'Retrieve our class, no need to clone it. 

    imgList.Images.Add(img.Image) 'Add the image first (I don't know for sure, but if you add the image after, wouldn't it require to redraw the ListView an extra time?). 
    ListView1.Items.Add(img.FileName, imgList.Images.Count - 1) 'Add the new item with the values from our class. 
End Sub 

Ve:

Şimdi ReportProgess() olayı işlemek için gidiyoruz

Ve bununla ilgili her şeyi kapsamalıydım.

Bu yardımcı olur umarız!

+0

Bu bir çekicilik gibi çalışır! Bu detaylı cevap için ve bazı aptalca hatalar için bana yardım ettiğin için teşekkür ederim ... Son bir sorum var: Yine de listeyi yenilemek/yeniden yüklemek istesem listeyi temizlemek zorunda kaldım. tekrar backgroundworker? –

+0

Ayrıca meraktan etrafında bu 2 sıra değiştirilmiş: 'imgList.Images.Add (img.Image) ListView1.Items.Add (img.FileName, imgList.Images.Count - 1) ' ve Başlangıçta olduğu gibi aynı hatayı yapıyordu, bu yüzden sorun hep birlikte miydi? –

+1

@DominikH: Evet, 'ListView' ve 'imgList 'işaretlerini kaldırabilirsiniz ve daha sonra BGW'yi yeniden çalıştırabilirsiniz. –