ImageListView

    • VB.NET

      ImageListView

      Anbei eine Winz-Solution, die zeigt, wie einfach man mit einer Listview viele Bilder zur Auswahl stellen kann. Im grunde geht's sogar komplett im Designer, also folgendes ist zu tun:
      1. ImageList aus der Toolbox aufs Form packen. (In gruppierter Toolbox findet man die Imagelist bei den "Komponenten" - bei sortierter Toolbox unter "I" (wer hätte das gedacht? ;) )
      2. Imagelist anwählen, im Eigenschaftenfenster deren Property Images klicksen, dann geht ein Dialog auf, mit dem man Images zufügen kann.
      3. Imagelist.ImageSize auf zB 150;150 einstellen
      4. ListView aufs Form packen. Deren Property View ist sogar für uns passend voreingestellt auf View.LargeIcon
      5. per SmartTag oder im Eigenschaftenfenster die LargeImageList-Eigenschaft setzen (oder wenn wolle auch die SmallImageList)
      6. im Eigenschaftenfenster auf Items klicksen, da geht ein Dialog auf, mit dem man ListViewItem zufügen kann
        Bei jedem ListViewItem den IconIndex angeben, sodass er auch ein Image aus der Imagelist addressiert
      Fertig - Code ist nicht zu schreiben, um zu diesem Ergebnis zu kommen:


      Der Vollständigkeit halber hab ich aber noch was gecodet, dass man auch zur Laufzeit Bilder zufügen oder löschen kann, und sogar den View-Mode kann man wechseln, dass man verschiedene Viewmodes mal ausprobieren kann. Hat man viele Bilder kann man so vlt. verschiedene Größen-Modi anbieten.

      Das Datenmodell
      Zuvor erkläre ich aber noch bischen abstrakter das Datenmodell eines Bilder/Icons zeigenden Listviews: Es ist nämlich nicht so, das die Images, die ein ListviewItem anzeigt, auch im ListviewItem drinne sind.
      Sondern es gibt 2 Auflistungen:
      1. die ListviewItems-Auflistung der ListView mit den ListviewItems drin
      2. die ImageList mit den Images drin
      Und jedes ListviewItem verweist nur auf ein Image - mittels IconIndex - es enthält das Image aber nicht (obwohls am Bildschirm dann so aussieht).
      Diese Konstruktion bietet wesentliche Vorteile gegenüber der intutitiven Erwartung, dass die Images im ListviewItem drinne wären. ZB. können mehrere ListviewItem dasselbe Icon anzeigen - das spart immens Resourcen.
      Aber solch wird in diesem Sample nicht ausgenutzt - hier wird für jedes neue ListviewItem ein eigenes Image in die ImageList geladen.

      Code

      VB.NET-Quellcode

      1. Imports System.IO
      2. Public Class frmImageListView
      3. Private Shared _ViewModes As View() = DirectCast([Enum].GetValues(GetType(View)), View())
      4. Public Sub New()
      5. InitializeComponent()
      6. OpenFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
      7. cmbViews.ComboBox.DataSource = _ViewModes
      8. End Sub
      9. Private Sub AnyButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btAddPicture.Click, btDeletePicture.Click
      10. Select Case True
      11. Case sender Is btAddPicture : AddImage()
      12. Case sender Is btDeletePicture
      13. For Each indx In From i In ListView1.SelectedIndices.Cast(Of Integer)() Order By i Descending
      14. ListView1.Items.RemoveAt(indx)
      15. Next
      16. End Select
      17. End Sub
      18. Private Sub AddImage()
      19. If OpenFileDialog1.ShowDialog <> Windows.Forms.DialogResult.OK Then Return
      20. Dim fi = New FileInfo(OpenFileDialog1.FileName)
      21. Dim img As Image
      22. Try
      23. img = Image.FromFile(fi.FullName)
      24. Catch ex As Exception
      25. MessageBox.Show("Laden fehlgeschlagen")
      26. Return
      27. End Try
      28. ImageList1.Images.Add(img)
      29. ListView1.Items.Add(fi.Name, ImageList1.Images.Count - 1)
      30. End Sub
      31. Private Sub cmbViews_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbViews.SelectedIndexChanged
      32. ListView1.View = _ViewModes(cmbViews.ComboBox.SelectedIndex)
      33. End Sub
      34. End Class
      Wie oben erwähnt, werden Images nicht der Listview zugefügt, sondern der ImageList (zeile #34) (wo die anderen Bilder ja auch drinne sind, die per Designer zugefügt wurden).
      Und ausserdem muss man natürlich auch ein ListViewItem zufügen - sonst sieht man ja nix (#35)
      Und dabei wiederum nicht vergessen, den IconIndex richtig zu setzen, damit das ListviewItem auch das neue Image aus der Imagelist anzeigt. Der IconIndex wird hier direkt als 2. Parameter der ListViewItems.Add( , ) - Methode übergeben, also ebenfalls #35

      Das Löschen (zeilen #18-20) sortiert die SelectedIndicees absteigend, und geht dann mit ForEach durch, sodass die hinteren ListviewItems als erste gelöscht werden, und so nicht die Reihenfolge der davor liegenden Items durcheinanderbringen (von denen ja noch welche zu löschen sind).

      Die View-Enum-Werte packe ich schlicht in ein Array (#5), und binde im Startup die Combobox dran (#10). Und was im Combobox_SelectedIndexChanged-Event passiert, ist ja wohl selbstverständlich, odr?

      Insgesamt weise ich drauf hin: Es ist nur ein Demo, und verhält sich nicht konsistent.
      ZB beim Zufügen werden Bilder und ListviewItem zugefügt, beim Löschen aber nur die LVI weggehauen.
      Im richtigen Leben muss man da mehr Hirnschmalz investieren, vor allem sinnreich konzipieren, und dann entsprechend umsetzen.
      Dateien
      • ImageListView.zip

        (52,42 kB, 285 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()