Laden...

Listview und Imagelist zusammenspiel!

Erstellt von telly168 vor 12 Jahren Letzter Beitrag vor 12 Jahren 5.187 Views
T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren
Listview und Imagelist zusammenspiel!

Hallo,
ich arbeite zur Zeit an einem Programm welches mir Bilder in einem Listview darstellt und diese bei auswahl in einen bestimmten Ordner verschiebt. Die Bilder werden per OpenFileDialog eingelesen und anschließend mit Hashcode in die Datenbank geschrieben(SqlLite) anschließend werden Vorschauen für die Bilder erstellt (im Listview). Die Bilder werden beim starten des Programm in eine Image List geschrieben die aus den Vorhanden Daten der Datenbank erstellt wird.
Leider bestehen nun 2 Probleme bei denen ich mir entweder nicht so sicher bin oder mir nicht klar ist ob das überhaupt richtig wie ich genau vorgehe.

Problem 1:
Erstellen von Thumbnails:


int maxLengt = GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows.Count;
            ImageList iconListKopie = new ImageList();
            iconListKopie.ImageSize = new Size(GlobalVar.iconBreite, GlobalVar.iconBreite);
          
            iconListKopie.Images.Clear();
            IntPtr hImgSmall;
            string FName;
            SHFILEINFO shinfo = new SHFILEINFO();
            
            int i = 0;
            while (i != maxLengt)
            {
                //Icon Size festlegen
                currentPath = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\Arbeitskorb" + "\\" + GlobalVar.ArbeitskorbName + "\\").ToString();
               FileInfo file = new FileInfo(currentPath + GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows[i]["Dat_NeuName"].ToString());
                string fileName = currentPath + GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows[i]["Dat_NeuName"].ToString();
                FName = GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows[i]["Dat_Name"].ToString();
               

                if (file.Extension == ".jpg" || file.Extension == ".png" || file.Extension == ".TIF")
                {
                    Image jpgThumb;
                    Image image;
                    image = Image.FromFile(fileName);
                    jpgThumb = image.GetThumbnailImage(GlobalVar.iconBreite, GlobalVar.iconHoehe, null, new IntPtr());
                    image.Dispose();
                    iconListKopie.Images.Add(jpgThumb);
                    
                    iconListKopie.Images.SetKeyName(i, GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows[i]["Dat_ID"].ToString());
                    
                }
                else
                {
                    hImgSmall = Icons.SHGetFileInfo(FName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Icons.SHGFI_ICON | Icons.SHGFI_LARGEICON);
                    System.Drawing.Icon myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
                    iconListKopie.ImageSize = new Size(GlobalVar.iconBreite, GlobalVar.iconHoehe);

                    iconListKopie.Images.Add(myIcon);
                    iconListKopie.Images.SetKeyName(i, GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows[i]["Dat_ID"].ToString());
                }
                    
                i++;
                
            };
            
            GlobalVar.IconList = iconListKopie;
            iconListKopie.Dispose();

        }

Hier erstelle ich alle Bilder die erkannt werden ist es kein Bild lasse ich das Icon aus der Shell32 suchen und einfügen. Die dauert ab 100 Bildern sehr lang.. aber leider weiss ich keine andere möglichkeit.
Das eigentlich Problem das hier entsteht entsteht beim Lösch vorgang. Entferne ich ein Bild aus der Liste und der Datenbank so muss die GESAMTE List und das Listview neu befüllen.
Leider versteh ich die Bindung von Listview und Imagelist nicht so ganz. Wie hängen diese zwei zusammen ? Entfernt er das Bild aus der Imagelist mit wenn ich das Item Remove?

Problem 2
WEnn ich Images Image Hinzufüge passiert das gleich ich muss immer das Gesamte Datenset neu laden und die Imageliste und die Icons neu erstellen das dauert wie schon erwähnt sehr lange.
Gibt es hier eine Methode das Datenset nur Änderung lesen zulassen und nur einzelne Bilder hinzfügen zulassen ohne alles neu erstellen zu müssen ?

Danke für eure Hilfe!
lg
telly

A
764 Beiträge seit 2007
vor 12 Jahren

Was dir bei deinen Problemen evt. helfen könnte, wäre ein anderes ListView zu verwenden. Ich denke dabei an ObjectListView.
Das benötigt zwar etwas Einarbeitungszeit, aber wenn du die hast, dann wirst du feststellen, dass sie sich lohnt. 😃

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

Hi
Danke für die Idee ich kann das Objekt. Leider: Ist meine Gesamt Oberfläche schon fertig und es liegen nur noch diese 2 Probleme wirklich vor.
Mir würde es schon viel weiterhelfen wenn mir jemand erklären könnte wie genau das Listview mit der Imagelist und den Items zusammenhängt.
Weiteres Problem immer noch noch mein Datenset. Ich muss wie gesagt immer die Gesamt List neu laden nicht nur einfach die die sich verändert haben.

Das ganze jetzt nocheinmal umzubauen wäre viel zu viel arbeit.

lg
telly

F
10.010 Beiträge seit 2004
vor 12 Jahren

Naja, du hast deine ganze Software falsch aufgesetzt und es kommt jetzt am ende erst zu den Problemen.

Du kannst nicht erwarten dann am Schluss mit viel Magie diese Fehler irgendwie zu beheben.

  1. Benutze ein UI Control das DataBinding unterstützt, sei es DataGridView, oder auch das ObjectListView ( das aber explizit nicht in kommerzielle Software darf ).

  2. Da du derjenige bist der die neuen Daten schreibt, bist du auch derjenige, der bis jetzt am DataSet vorbei schreibt, was eben zu diesen Folgefehlern führt.

Die Arbeit steht sowieso an, und genauso wirst du einiges andere suboptimal gelöst haben.

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

Hallo,
Ich bin auf die Bildvorschau angewiesen egal was ist. Ich muss also das Listview nutzen.
Was heisst am Datenset vorbei schreibt ? Ich schreibe in das Dateset mit Select Insert Update Anweisung.
Ich kann die Datenbank immer noch ändern wenn das mir so viel erleichtert! Daran solls nicht scheiter.
Die Software wird allerdings veröffentlich von dahher kommt das ObjektListView schon nicht mehr in betracht.
lg
telly

F
10.010 Beiträge seit 2004
vor 12 Jahren

Ein DGV kann auch Bilder/vorschau anzeigen, wo ist da das Problem?

Und wenn du das DataSet neu laden musst, schreibst du wohl doch dran vorbei, denn sonst wären die Änderungen doch gleich dort vorhanden.
Bei DataBinding wäre auch das Update sofort passiert, da muss dann nichts mehr händisch eingepflegt werden.

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

Ok jetzt versteh ich was du meinst.
Damit es deutlicher wird hab ich ein Bild im Anhang.
Die Bilder werden aus einem bzw. aus mehreren Verzeichnissen gelesen und in die Imagelist (wie oben im Code angezeigt) gelesen.
Wie soll ich das per Update einbinden, ohne ALLE Bilder neu zu erstellen, beim lösch bzw einbind vorgang.
lg
telly

F
10.010 Beiträge seit 2004
vor 12 Jahren

Wenn du die Daten nicht in das UI Element friemelst ( wie du es mit dem ListView tust) erstellst du beim ersten Aufruf ja schon eine Liste mit den vorhandenen Daten.

Diese kannst du dann updaten, indem du nicht mehr vorhandene Löscht und neu oder geänderte hinzufügst/bearbeitest.
So müssen nur für etwaige Änderungen die ganzen schritte durchgeführt werden.

Und da du eine Liste hast, lässt sich diese auch einfach binden.

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

Sorry versteh leider nicht was du mir damit sagen willst! (vllt stell ich mich auch gerade bissel drum dran)

F
10.010 Beiträge seit 2004
vor 12 Jahren

Mal ganz von Vorne.

  1. Wo und wie wird die DataTable befüllt?
  2. GlobalVar.DB.edScanDS.Tables["DateiDokLeer"] ist scheinbar eine Globale variable.
  3. Warum muss hier das Thumbnail immer und immer wieder erstellt werden?
  4. Du hast schonmal von foreach gelesen?

Hintergrund der Fragen:

  1. Man verwendet keine Globalen Variablen in klassen, das ist viel zu fehleranfällig. Die Variablen werden entweder direkt funktionen übergeben oder per DI/IOC "injected".

  2. Wenn du schon Thumbnails erzeugst, warum speicherst du die nicht in der DB?

  3. Mit foreach wäre deine Funktion 200mal besser lesbar und wartbar.


foreach ( DataRow row in GlobalVar.DB.edScanDS.Tables["DateiDokLeer"].Rows)
{
    FName = row["Dat_Name"] as string;
...
}

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

also
zu 1
in der Database


      private void DateiDokLeer()
        {
            string SqlText = "Select * from Datei where Dok_ID ISNULL";
            DatenAdapter = new SQLiteDataAdapter(SqlText, connction);
            DatenAdapter.Fill(edScanDS, "DateiDokLeer");
        }

zu 2
Ja das ist eine GlobalVariable und ja das weiss ich. (Sorry aber so war es einfach leichter 😉)
zu3
Sorry bin nicht gerade so gut in Datenbanken wie speichert man Thumbnail in Datenbanken ?
-> Nutze SQLlite (bzw MUSS)
zu 4
Ja ich kenne foreach allderings ist das maxlenth zum begrenzen der Anzeige gedacht und noch aus der start funktionen welche die Gesamte liste an Thumbnails für die DateiDokLeer erstellt.
Wenn mehr wie 20 Hinzugefügt werden werden in einem Hintergrundprozess die ganze liste neu erstellt !
was in dem Fall bei Speichern von Thumbnails nicht passieren müsste 😃(

Hinweis von winSharp93 vor 12 Jahren

Bitte CSHARP-Tags statt CODE-Tags verwenden!

F
10.010 Beiträge seit 2004
vor 12 Jahren

(Sorry aber so war es einfach leichter 😉)

In der EDV ist nichts so beständig wie das Provisorium, also mach es gleich richtig.

Mach in der Tabelle einfach eine "blob" spalte, die die byte[] Daten des Images enthält.
Wenn ein DGV auf so eine byte[] Spalte in einer DataTable stösst versucht es sowieso ein Image draus zu verstehen und zeigt es an.

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

ok erst mal vielen dank für deine Hilfe.
Allerdings war mein Thema das Datenset Update.
Muss ich jetzt das Gesamte Datenset neu einlesen oder nich und ich lese das ganze in ein Listview ein oder gibt es eine möglichkeit genau die gleiche Darstellung wie hier in meine Listview beim DGV zu erstellen .
lg
telly 😄

F
10.010 Beiträge seit 2004
vor 12 Jahren

Wenn du am DataSet vorbei Änderungen in der DB vornimmst, musst du die neuen Daten laden.
Wenn DU das nicht vorgesehen hast ( z.b. Zeitstempel der letzten Änderung ) kannst du nur alles lesen.
Du kannst aber natürlich die Daten in eine zweite DataTable lesen, und nur die geänderten/neuen Datensätze übertragen.
DataTable.Merge-Methode (DataTable)

Und was ist da das betroffene ListView?

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

Alle Listviews sind davon betroffen.
Die Darstellung wie oben im Bild sind ja Listviews. Wie du schon gesagt hast kann ich in einem DGV auch Bilder anzeigen. Wenm ich deine möglichkeit in betracht ziehe die Thumbs im Grid darstellen zu lassen ist einfach meine frage: Kann ich im DGV das Thumbnail genau so darstellen lassen wie in meinem Bild vom Listview ?

F
10.010 Beiträge seit 2004
vor 12 Jahren

Wenn das alles ListViews sind, dann nein, denn das DGV stellt die Daten Zeilenweise dar.

Aber du kannst das ListView ja ohne weiteres im VirtualMode=True betreiben.
Das mit der DataTable zu verbinden ist dann eher simple.
ListView.VirtualMode-Eigenschaft

Hinweis von herbivore vor 12 Jahren

Auch wenn mir klar ist, dass es hier Berührungspunkte zum Datenbankzugriff und zu Grafikoperationen gibt, sollte der Thread doch bitte immer möglichst dicht bei eigentlichen GUI-Thema bleiben.

T
telly168 Themenstarter:in
40 Beiträge seit 2012
vor 12 Jahren

ok
ich werde es versuchen
Danke noch mal
closed 😃