vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Schützen Sie Ihre Software vor Software-Piraterie - mit sevLock 1.0 DLL!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 17:47

... also auch, wenn das ListView nicht mehr das aktive Control ist.

Ich versuche schon seit Tagen das Problem zu lösen.
Bekomme es aber nicht hin.
Gegeben sei ein einspaltiges ListView "liv_Folders"

Dachte, das ist einfach, dann färbe ich die Zellen beim Verlassen des Controls einfach manuell ein und entfärbe diese wieder, wenn das Control den Focus wieder erhält:

    Private Sub liv_Folders_Enter(sender As Object, e As EventArgs) Handles _
      liv_Folders.Enter
        Debug.Print("Folders Enter")
        For I = 0 To liv_Folders.Items.Count - 1
            If liv_Folders.Items(I).Selected = True Then
                liv_Folders.Items.Item(I).SubItems(0).BackColor = _
                  Color.FromKnownColor(KnownColor.Window)
                liv_Folders.Items.Item(I).SubItems(0).ForeColor = _
                Color.FromKnownColor(KnownColor.WindowText)
            End If
        Next
    End Sub
 
    Private Sub liv_Folders_Leave(sender As Object, e As EventArgs) Handles _
      liv_Folders.Leave
        Debug.Print("Folders Leave")
    End Sub
    Private Sub liv_Folders_Validated(sender As Object, e As EventArgs) Handles _
      liv_Folders.Validated
        Debug.Print("Folders Validated")
        For I = 0 To liv_Folders.Items.Count - 1
            If liv_Folders.Items(I).Selected = True Then
                liv_Folders.Items.Item(I).SubItems(0).BackColor = _
                  Color.FromKnownColor(KnownColor.Red) 'Highlight
                liv_Folders.Items.Item(I).SubItems(0).ForeColor = _
                Color.FromKnownColor(KnownColor.Yellow) 'HighlightText
            End If
        Next
    End Sub
Aber selbst "liv_Folders_Validated" wird noch ausgeführt, bevor der selektierte Eintrag tatsächlich den Focus verliert und das System damit selbst die Backcolor und Frontcolor der Selektion auf Nonselect-Farben setzt.
Aber eben damit geht meine Einfärbung verloren.

Diese funktioniert nicht mal, wenn ich meine Einfärbeschleife in das "Control_Enter" eines anderen Controls lege.

Wie kann ich das Problem anders lösen?
Habe schon vieles versucht, komme aber auf keine einfache Lösung.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 30.12.22 17:56

Hallo!

Im Forum bitte verständlich das Problem bzw. die Zielstellung schildern und keinen Code posten, der nicht funktioniert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 18:14

Hi Manfred,

sorry - ich dachte, ich hätte das Problem deutlich beschrieben.
Also nochmal..

Ich habe ein Listview-Control neben anderen Controls wie z.B. einer zweiten ListView-Control und einer Textbox auf meiner Form.

Also
1. Eine Verzeichnisliste "liv_Folders", welche die Verzeichnisse eines definierten Stammordners anzeigt
2. Eine Dateiliste "liv_Files", welche die Dateien anzeigt, die in dem "liv_Folders" selektierten Verzeichnisses gespeichert sind
3. Eine Textbox "txb_Inghalt", welche den Text-Inhalt der in der "Liv_Files" ausgewählten Text-Datei anzeigt

Hier möchte ich, dass der ausgewählte (selektierte) Ordner-Eintrag in der Liv_Folders-Liste angezeigt bleibt, wenn ich z.B. einen Eintrag in der liv_Files anklicke.
Und dass die selektierte Datei in der "Liv_Files" angezeigt bleibt, wenn der Benutzer die Textbox "txb_Inhalt" anklickt.

Damit die User immer in den beiden ListViews das gewählte Verzeichnis und die gewählte Datei markiert sehen, deren Datei-Text-Inhalt gerade in der "Txb_Inhalt" angezeigt wird.

Sobald eine der ListViews den Focus verliert, wird aber damit auch deren gehighlighte Selektion unsichtbar.
Eben dies will ich verhindern.

Beitrag wurde zuletzt am 30.12.22 um 18:18:51 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 30.12.22 18:31

Mir ist nach wie vor nicht klar, was Du erreichen möchtest.
Für die Anzeige der Ordnerstruktur verwendet man ein Treeview-Control.
Was verstehst Du unter einer Verzeichnisliste?
Steht in jedem Item der Liste der gesamte Pfad zu einer bestimmten Datei?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 18:52

Eine Treeview brauche ich nicht, da ich die Benutzung so einfach als möglich gestalten möchte.

Daher lasse ich in der Listview "liv_Folders" alle Unterordner des anderweitig selektierten Stammverzeichnisses (Archiv-Stamm-Verzeichnis) auflisten.

Dieses Listview "liv_Folders" enthält also die Verzeichnisnamen aller Unterverzeichnisse des Stammordners.
Dies nenne ich eben "Verzeichnisliste".
In den Einträgen stehen nur die reinen Verzeichnisnamen, welche sich im Stammverzeichnis befinden.

Wählt der Benutzer in dieser "Liv_Folders" eines dieser Verzeichnisse aus, werden alle Txt-Dateien, die sich in diesem Verzeichnis befinden, in der 6-spaltigen "liv_Files" aufgelistet.
Das ist meine "Dateiliste".
In diesen Einträgen stehen nur die Dateinamen(und in je einer weiteren Spalte "Endung", "Grösse", "Änderungsdatum", "Erstellungsdatum", "Zugriffsdatum") der Dateien, welche sich im o.g. ausgewählten Verzeichnis der "liv_Folders" befinden.

Wählt der Benutzer in der "Liv_Files" eine dieser Dateien aus, wird deren Text-Inhalt in der Textbox "txb_Inhalt" angezeigt.

Den Pfad zu der Textdatei ermittle ich aus der Verknüpfung von Stammordner & selektiertem Verzeichnis-Eintrag der "Liv_Folders" & Dateinamen & Endung aus dem selektierten Eintrag in der "liv_Files"

Und eben hierbei sollen immer die selektierten Einträge der "liv_Folders" und "liv_Files" angezeigt bleiben, damit der Benutzer damit leicht den Pfad der angezeigten Text-Datei nachvollziehen kann.

P.S. Kein Treeview auch deshalb, damit der Benutzer die "Liv_Folders" durch Klick auf den Spaltenkopf auch Auf-/abwärts sortieren kann.
Dieselbe Sortiermöglichkeit gilt auch für die sechs Spalten der "liv_Files"

Beitrag wurde zuletzt am 30.12.22 um 18:57:43 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 30.12.22 19:01

Das Treeview ist die einfachste Methode, durch die ein Benutzer durch
eine Ordnerstruktur navigieren kann.

Du schreibst, dass Du alle Unterordner auflistest. Das geht nicht.
Du kannst nur die Teilpfade ab dem Stammordner in eine Liste eintragen.
"Reine Verzeichnisnamen"? Das reicht nicht aus.

Verwende ein Dataset.
Eine Datatable enthält in den Zeilen die Teilpfade, eine zweite
Datatable wird mit einer Datarelation verknüpft und enthält die Dateinamen.

Wenn Du mit ListViews arbeiten willst, musst Du vermutlich den jeweils selektierten
Listeneintrag temporär einfärben (Backcolor).
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 19:26

Danke Dir!

Das Treeview scheidet aus, da hier auch verschachtelte Ordnerstrukturen angezeigt/ausgewählt und diese nicht sortiert werden können.

Den "Stamm-Ordner" des Archivs kann nur der Admin ändern - nicht der User.
Die Namen der Unterordner des Archiv-Stamm-Verzeichnisses dienen in meinem Projekt als "Gruppen"-Namen.

Der komplette Verzeichnispfad ist hierbei für den User irrelevant - der muss eben nur die Gruppennamen (Verzeichnisse im Stammverzeichnis) angezeigt bekommen."
Nur diese Verzeichnisse der 1. Ebene werden dem User in der "liv_Folders" angezeigt und der User kann diese "Gruppennamen" Auf-/Absteigend sortiert anzeigen lassen.
Ja, nur eben diese Teilpfade ab dem Stammordner sind dafür relevant und sollen angezeigt werden.

Wählt der User dann eine "Gruppe", also ein Verzeichnis, bekommt er alle Textdateien, die sich in diesem Verzeichnis befinden, in der "liv_Files" angezeigt.

Hier kann er wieder eine Datei selektieren, deren Inhalt ihm dann in der "txb_Inhalt" angezeigt wird.

Den Listeneintrag temporär einzufärben, habe ich versucht, siehe meinen Code im EP.
Aber da macht mir die Select/Unselect (highlight/Normalfarbe) der internen Markierungsfunktion des ListView-Controls einen Strich durch die Rechnung.

Ich lasse beim Ausführen der "liv_Folders_Validated"-Prozedur die Backgroundfarbe auf meine Markierungsfarbe setzen.
Das wird auch ausgeführt.

Aber da die Listview-interne De-Highlighting-Funktion beim Verlassen des Controls wohl erst nach dem v.g. Validated ausgeführt wird, wird damit meine Einfärbung verworfen, sobald das Control anschliessend selbst die Markierung entfernt und die Backcolor auf die Hintergrundfarbe des Controls setzt.

Genau das ist mein Problem.
Und hierfür suche ich eine Lösung.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 30.12.22 19:38

Also nur die Verzeichnisse der ersten Unterebene.
Ich bleibe bei meinem Vorschlag mit dem Dataset.
Wenn es um das Sortieren geht, kann das in einem gebundenen Gridview
einfach erledigt werden.

Schau Dir mal so ein Beispiel an.
https://www.vbarchiv.net/forum/id22_i94845t94842_kaskadierte-datagridviews-mit-datarelations.html

In Deinem Fall benötigst Du nur eine Relation.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 19:40

Komisch...
jetzt habe ich einen Test-Button mit:

 
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles _
  Button1.Click
        For I = 0 To liv_Folders.Items.Count - 1
            If liv_Folders.Items(I).Selected = True Then
                liv_Folders.Items.Item(I).SubItems(0).BackColor = _
                  Color.FromKnownColor(KnownColor.Red) 'Highlight
                liv_Folders.Items.Item(I).SubItems(0).ForeColor = _
                Color.FromKnownColor(KnownColor.Yellow) 'HighlightText
            End If
        Next
End Sub
gebastelt und erwartete eigentlich, dass dieser beim Anklicken die im "liv_Folders" selektierte Zeile einfärbt.

Macht er aber nicht.
Weder, wenn das Control "liv_Folders" aktiv ist, noch, wenn ein anderes Control aktiv ist.
In der Einzelschritt-Verfolgung führt das Script aber alles aus.
Nur wird die Farbänderung im Control eben nicht angezeigt.
Warum nicht?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 19:45

Hi Manfred,

danke Dir!
Ich bin gerade am Umstieg von VB6 auf VB.net und wollte eigentlich erst mal ganz klein anfangen, bevor ich mich an so grosse Sachen wie Binding usw. mache.
Daher erst mal dieses einfache Testprojekt.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 20:17

Aha...

das funktioniert:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles _
      Button1.Click
        My.Settings.FoldersIndex = liv_Folders.SelectedItems(0).Index
        liv_Folders.SelectedItems.Clear()
 
        liv_Folders.Items.Item(My.Settings.FoldersIndex).SubItems(0).BackColor _
          = Color.FromKnownColor(KnownColor.Red) 'Highlight
        liv_Folders.Items.Item(My.Settings.FoldersIndex).SubItems(0).ForeColor _
        = Color.FromKnownColor(KnownColor.Yellow) 'HighlightText
    End Sub
Aber nur, wenn ich die Selektion lösche.
D.h. ich muss meine ausgewählten Einträge der "liv_Folders" in ein Variablen-Array (in diesem Test ist es nur die erste markierte Zeile) sichern, dann die Selektion der "liv_Folders" aufheben, die Zellen einfärben und mit dem Variablen-Array weiterarbeiten.

Gibt es keine bessere Lösung?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 30.12.22 20:55

Du musst das Item vermutlich deselektieren und den Item-Index separat merken.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 30.12.22 21:05

Hi Manfred,
also so, wie ich es in meinem Post von 20:17Uhr beschrieben habe?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Beispiel Master (Ordner) Child (Dateien) 
Autor: Manfred X
Datum: 31.12.22 18:57

Winforms-Beispiel / ein geeigneter Stammordner muss angegeben werden
Ein Filter beim Enum(m)erieren der Dateien könnte gesetzt werden (*.txt)
Public Class frmFoldersAndFiles
 
    Dim basefolder As String = "C:\xxxxx"  'Basisordner angeben
 
    Dim dtFolders, dtFiles As DataTable
    Dim bsFolders, bsFiles As New BindingSource
    Dim WithEvents dgvFolders, dgvFiles As New DataGridView
    Dim dsFoldersFiles As DataSet
 
    Dim tboFileContent As New TextBox With
        {.Parent = Me, .Left = 10, .Top = 320, .Height = 150, .Width = 600,
        .Multiline = True}
 
 
    Private Sub frmFoldersAndFiles_Load(sender As Object,
                                        e As EventArgs) Handles MyBase.Load
 
        Me.FormBorderStyle = FormBorderStyle.Fixed3D
        Me.Size = New Size(700, 560)
 
        With dgvFolders
            .Size = New Size(300, 300)
            .Location = New Point(10, 10)
            .DataSource = bsFolders
            .Parent = Me
        End With
        With dgvFiles
            .Size = dgvFolders.Size
            .Location = New Point(320, 10)
            .DataSource = bsFiles
            .Parent = Me
        End With
 
        Me.Show()
 
        CreateFilesAndFolders()
    End Sub
 
 
    Private Sub dgvFiles_RowHeaderMouseClick(sender As Object,
          e As DataGridViewCellMouseEventArgs) Handles _
            dgvFiles.RowHeaderMouseClick
 
        'Anzeige einer Textdatei beim Click auf den Zeilenkopf des Grid mit 
        ' Dateien
        '(kann man besser machen)
 
        Dim row As DataGridViewRow = dgvFiles.Rows.Item(e.RowIndex)
        Dim folderid As Integer = CInt(row.Cells("FolderID").Value)
 
        Dim foldername As String =
            dgvFolders.Rows.Item(folderid - 1).Cells("Subfolder").Value.ToString
        Dim filename As String =
            IO.Path.Combine(basefolder, foldername, row.Cells( _
              "Filename").Value.ToString)
 
        Try
            tboFileContent.Text = IO.File.ReadAllText(filename)
            Me.Text = IO.Path.GetFileName(filename)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
 
 
    Private Function CreateFilesAndFolders()
 
        dtFiles = New DataTable : dtFolders = New DataTable
 
        'Tabellenspalten erstellen
        With dtFolders
            .TableName = "folders"
            .Columns.Add("ID", GetType(Integer))
            .Columns.Add("Subfolder", GetType(String))
        End With
 
        With dtFiles
            .TableName = "files"
            .Columns.Add("ID", GetType(Integer))
            .Columns.Add("FolderID", GetType(Integer))
            .Columns.Add("Filename", GetType(String))
        End With
 
        'Filesystem-Daten in die Tabellen einlesen
        Dim folderid, fileid As Integer, subfolder As String
        For Each fld As String In
            IO.Directory.GetDirectories(basefolder, "*.*", _
              IO.SearchOption.TopDirectoryOnly)
 
            folderid += 1
            subfolder = fld.Replace(basefolder, "").Replace("\", "")
            dtFolders.Rows.Add(folderid, subfolder)
 
            For Each file As String In
                IO.Directory.EnumerateFiles(fld, "*.*", _
                  IO.SearchOption.TopDirectoryOnly)
 
                fileid += 1
                dtFiles.Rows.Add(fileid, folderid, IO.Path.GetFileName(file))
            Next file
        Next fld
 
        'Dataset zusammenstellen
        dsFoldersFiles = New DataSet
        With dsFoldersFiles.Tables
            .Add(dtFolders)
            .Add(dtFiles)
        End With
 
        'Datarelation für Master->Child
        Dim pc As DataColumn = dtFolders.Columns("ID")
        Dim cc As DataColumn = dtFiles.Columns("FolderID")
        dsFoldersFiles.Relations.Add("FoldersFiles", pc, cc)
 
        'Parent-Child-Koordination
        bsFolders.DataSource = dsFoldersFiles
        bsFolders.DataMember = "Folders"
 
        bsFiles.DataMember = "FoldersFiles"
        bsFiles.DataSource = bsFolders
 
        'nach Belieben .....
        dgvFolders.Columns("ID").Visible = False
        dgvFiles.Columns("FolderID").Visible = False
    End Function
End Class
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Nachgereicht 
Autor: Manfred X
Datum: 01.01.23 11:14

Private Sub dgvFiles_RowHeaderMouseClick(sender As Object,
          e As DataGridViewCellMouseEventArgs) Handles _
            dgvFiles.RowHeaderMouseClick
 
        'Anzeige einer Textdatei beim Click auf einen Zeilenkopf im Grid mit 
        'den Dateinamen
 
        'an GridView gebundene Bindingsource
        Dim rowview As DataRowView = bsFiles(e.RowIndex)
 
        'Datarelation verwenden
        'Datarowview weist die Datarow der gebundenen Tabelle (row-Eigenschaft)  
        Dim parentrow = rowview.Row.GetParentRow("FoldersFiles")
        Dim subfoldername As String = parentrow("Subfolder")
 
        'Den kompletten Pfad der Datei zusammenstellen
        Dim filename As String = IO.Path.Combine(basefolder, 
                                  subfoldername, rowview.Row( _
                                    "Filename").ToString)
 
        Try
            tboFileContent.Text = IO.File.ReadAllText(filename)
            Me.Text = IO.Path.GetFileName(filename)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
 
End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 01.01.23 15:00

Hi Manfred,

danke Dir für die Beispiele.
Diese helfen jedoch auch nicht wirklich für das Problem, die selektierte Zelle(bzw. Zeile) markiert zu lassen, sobald das Control den Focus verliert, oder übersehe ich da was?
Ist für mein Winz-Testprojekt wohl auch etwas oversized.
Mir reichen die Arrays Folder und Files, mit welchen ich meine Listviews befüllen lasse.
Bin da gerade mit meinen ListViews am Basteln, um die Sache mit den markierten Zellen in den Griff zu bekommen.
Aber das gestaltet sich doch als recht schwierig...

Ein gutes Neues Jahr wünsche ich
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 01.01.23 19:23

Hallo!

Oversized?
Ich behaupte, Du benötigst bei Verwendung von Listen wesentlich mehr Code als ich.
Ein Teil meines Codes kommt zustande, weil ich den Formular-Designer nicht verwendet habe.

Die Darstellung der markierten Zellen/Zeilen in einem DataGridView
hat nichts mit dem Fokus zu tun. Auch bei einem Fokusverlust bleiben sie erhalten.

Die Grids haben aber eine eigene Navigation. Mit der Tab-Taste kann man
sich durch die Zellen des fokussierten Grids bewegen (StandardTab-Eigenschaft).
Das Verhalten dieses Controls kann umfassend eingestellt werden (z.B.
Readonly, AllowuserToAddrows, AllowuserToDeleteRows, Selectionmode usw.)
- z.B. im Load-Event der Form.

Beitrag wurde zuletzt am 01.01.23 um 19:41:06 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 04:21

Also bislang habe ich:

    Private Sub liv_Folders_ItemSelectionChanged(sender As Object, e As _
      ListViewItemSelectionChangedEventArgs) Handles _
      liv_Folders.ItemSelectionChanged
        For i = 0 To liv_Folders.Items.Count - 1
            liv_Folders.Items.Item(i).SubItems(0).BackColor = _
              Color.FromKnownColor(KnownColor.Window)
            liv_Folders.Items.Item(i).SubItems(0).ForeColor = _
            Color.FromKnownColor(KnownColor.WindowText)
        Next i
 
        If liv_Folders.SelectedItems.Count > 0 Then
            ' Filesliste neu laden
            foldersAuswertung(liv_Folders.SelectedItems.Count)
        End If
    End Sub
und

    Private Sub liv_Folders_Leave(sender As Object, e As EventArgs) Handles _
      liv_Folders.Leave
        If liv_Folders.SelectedItems.Count > 0 Then
            For i = 0 To liv_Folders.Items.Count - 1
                selFolders(i) = liv_Folders.Items(i).Selected
            Next i
        End If
        liv_Folders.SelectedItems.Clear()
        For i = 0 To liv_Folders.Items.Count - 1
            If selFolders(i) = False Then
                liv_Folders.Items.Item(i).SubItems(0).BackColor = _
                  Color.FromKnownColor(KnownColor.Window)
                liv_Folders.Items.Item(i).SubItems(0).ForeColor = _
                Color.FromKnownColor(KnownColor.WindowText)
            Else
                liv_Folders.Items.Item(i).SubItems(0).BackColor = _
                  Color.FromKnownColor(KnownColor.Red) 'Highlight
                liv_Folders.Items.Item(i).SubItems(0).ForeColor = _
                Color.FromKnownColor(KnownColor.Yellow) 'HighlightText
            End If
        Next i
    End Sub
Damit scheint schon mal das Markiert-Bleiben der Zellen zu klappen, wenn ein anderes Control den Focus erhält.

Aber danke Dir für Deine Hilfe - werde mich sicher noch im Zuge des Erlernens von VB.net mit Deinem Script auseinandersetzen.

Momentan scheint die Sache mit den ListViews auch zum Ziel zu führen.

Beste Grüsse
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 02.01.23 15:27

Hallo!

Das Listview-Control besitzt eine HideSelection-Eigenschaft.
Hast Du das ausprobiert?

Dir ist bekannt, dass Listviewitems eine Tag-Eigenschaft besitzen, in die
man Informationen/Daten eintragen kann (also z.b. den Wert für selected)?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 15:30

Servus Manfred,

habe eben Dein Datagrid-Beispiel mal als Testprojekt gestartet.
Das sieht ja sehr gut aus.

Danke Dir vielmals!

Was mir auffällt:
- Gesperrte Ordner wie "C:\Dokumente und Einstellungen" führen beim Einlesen (Stammverzeichnis: "C:\") zum Programmabbruch

Ich brauche ja sechs Spalten in der Files-Datagrid: "Filename", "Extension", "LastWriteTime", "CreationTime", "LastAccessTime"

Das habe ich so gelöst:

        Dim fileDetail As IO.FileInfo
'...
        With dtFiles
            .TableName = "files"
            .Columns.Add("ID", GetType(Integer))
            .Columns.Add("FolderID", GetType(Integer))
            .Columns.Add("Filename", GetType(String))
            .Columns.Add("FileExtension", GetType(String))
            .Columns.Add("FileCreationTime", GetType(Date))
            .Columns.Add("FileLastAccessTime", GetType(Date))
            .Columns.Add("FileLastWriteTime", GetType(Date))
        End With
 
        'Filesystem-Daten in die Tabellen einlesen
        Dim folderid, fileid As Integer, subfolder As String
        For Each fld As String In
                IO.Directory.GetDirectories(basefolder, "*.*",
                  IO.SearchOption.TopDirectoryOnly)
 
            folderid += 1
            subfolder = fld.Replace(basefolder, "").Replace("\", "")
            dtFolders.Rows.Add(folderid, subfolder)
 
            For Each file As String In IO.Directory.EnumerateFiles(fld, "*.*", _
              IO.SearchOption.TopDirectoryOnly)
                fileDetail = My.Computer.FileSystem.GetFileInfo(file)
 
                fileid += 1
                    dtFiles.Rows.Add(fileid, folderid, _
                      IO.Path.GetFileNameWithoutExtension(file), _
                      IO.Path.GetExtension(file), fileDetail.CreationTime, _
                      fileDetail.LastAccessTime, fileDetail.LastWriteTime)
                Next file
        Next fld
'...
Edit: Neee, die beiden Punkte habe ich noch nicht getestet.
Danke Dir - werde mich da mal ranmachen.
Das mit den Tags anstelle des Arrays wird sicher klappen.
Aber ob das alleine mit der HideSelection funktioniert, ohne tatsächlich die Selektion zu leeren?
Muss mal schauen.

Beitrag wurde zuletzt am 02.01.23 um 15:33:40 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 15:39

P.S. Gefällt mir besser, Deine DataGrid-Lösung.
Mille Gracie!
Die werde ich in mein Projekt übernehmen
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 02.01.23 16:05

Die File-Enumerations-Methoden des Framework brechen ab, wenn im Dateisystem
eine Sperre auftritt.
Man muss deshalb direkt die APIS für das Dateisystem verwenden
(FindFirstFile, FindNextFile).

Ich habe dafür eine komfortable Klasse erstellt, die ich aber wegen der
Forenbeschränkung (5 MB) hier nicht posten kann.
Aber es gibt Beispiele:
https://www.vbarchiv.net/forum/read.php?f=10&t=76877&i=76880
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 17:34

Soooo,

das sieht doch schon mal fein aus, mit dem eingebauten Datagrid.
Ist wirklich besser, als menie Frickellösung

Nur...

Kann die Breite der linken Markierungsspalte auch durch Code geändert werden?
 dgv_Files.Columns(0).Width = My.Settings.FilesSpaltenbreite1
ändert nur die Breite der ersten Inhaltsspalte, also in der Dgv_Folders die Spalte "Subfolders" bzw. in der Dgv_Files die Spaltenbreite der Spalte "ID".

Kann die Schriftart/-Grösse der DGV-Inhalte geändert werden?

Können die Spaltenköpfe und ggf. die linke Markierungsspalte anders eingefärbt werden?

Wenn ich einen Dateinamen in der Dgv_Files (oder einen Ordnernamen in der Dgv_Folders) ändere, muss ich dann manuell im Filesystem diese Datei(das Verzeichnis) entsprechend umbenennen und dann die Tables neu laden?

Muss mich in das DGV einarbeiten.
Damit habe ich noch nie wirklich gearbeitet.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Übersicht DatagridView Styles 
Autor: Manfred X
Datum: 02.01.23 18:06

Hallo!

Ich vermute mit "Markierungsspalte" meinst Du den Rowheader der Rows (Zeilen).

'nach Belieben
dgvFolders.RowHeadersWidth = 10

Das Grid verfügt über eine Font-Eigenschaft.
dgvFolders.Font = New Font("Arial", 12)

Für Spalten kann dieser Font überschrieben werden.
dgvFolders.Columns("ID").DefaultCellStyle.Font = New Font("Arial", 10)

Der Spaltenkopf kann eingefärbt werden.
dgvFolders.Columns("ID").HeaderCell.Style.BackColor = Color.Yellow

Die Spalte kann eingefäbt werden.
dgvFolders.Columns("ID").DefaultCellStyle.BackColor = Color.Green

Auch einzelne Zellen können gefärbt werden.

Der Zeilenkopf kann eingefärbt werden.
dgvFolders.RowHeadersDefaultCellStyle.BackColor = Color.LightBlue

Schau Dir die verschiedenen Style-Klassen an.
Es gibt eine Hierarchie: Cell -> Row -> Column -> Grid
Style-Einstellungen einzelner Zellen besitzen die höchste Priorität.

Umbennenungen von Files oder Subfolders sind im Dateisystem vorzunehmen. (neu laden)
Die Grids sollten ReadOnly gesetzt sein.

Beitrag wurde zuletzt am 02.01.23 um 18:07:19 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 18:35

Super,

viiiiielen Dank, Manfred!
Das Dgv ist ja eine eierlegende Wollmilchsau
Damit geht viel mehr, als in den LVs.
Da muss ich mich echt in dessen Benutzung einlesen - Habe dieses Kapitel im Buch bisher immer überblättert.

Ich quäle mich gerade mit der Einbindung Deines verlinkten APis-Scripts in Dein Script.
Im Moment funktioniert das Einlesen, nur, dass beim Verzeichniswechsel die neuen Fileeinträge unten an die vom alten Verzeichnis noch eingetragenen Fileeinträge angehängt werden.

    Private Function CreateFilesAndFolders()
        Dim verzeichnisListe As New List(Of String)
        Dim DateiListe As New List(Of String)
        Dim fileDetail As IO.FileInfo
        dtFiles = New DataTable : dtFolders = New DataTable
        'Tabellenspalten erstellen
        With dtFolders
            .TableName = "folders"
            .Columns.Add("ID", GetType(Integer))
            .Columns.Add("Subfolder", GetType(String))
        End With
 
        With dtFiles
            .TableName = "files"
            .Columns.Add("ID", GetType(Integer))
            .Columns.Add("FolderID", GetType(Integer))
            .Columns.Add("Filename", GetType(String))
            .Columns.Add("FileExtension", GetType(String))
            .Columns.Add("FileLastAccessTime", GetType(Date))
            .Columns.Add("FileLastWriteTime", GetType(Date))
            .Columns.Add("FileCreationTime", GetType(Date))
        End With
 
        'Filesystem-Daten in die Tabellen einlesen
        Dim folderid, fileid As Integer, subfolder As String
 
        'verzeichnisListe
        FindAllDirs(My.Settings.HauptPfad, "*.*", verzeichnisListe)
        For Each verzeichnis As String In verzeichnisListe
            folderid += 1
            subfolder = verzeichnis.Replace(My.Settings.HauptPfad, "").Replace( _
              "\", "")
            dtFolders.Rows.Add(folderid, subfolder)
 
            ' DateiListe
            FindAllFiles(verzeichnis, "*.*", DateiListe)
            For Each datei As String In DateiListe
                fileDetail = My.Computer.FileSystem.GetFileInfo(datei)
                fileid += 1
                dtFiles.Rows.Add(fileid, folderid, _
                  IO.Path.GetFileNameWithoutExtension(datei), _
                  IO.Path.GetExtension(datei), fileDetail.LastAccessTime, _
                  fileDetail.LastWriteTime, fileDetail.CreationTime)
            Next
        Next
 
        'Dataset zusammenstellen
        dsFoldersFiles = New DataSet
        With dsFoldersFiles.Tables
            .Add(dtFolders)
            .Add(dtFiles)
        End With
 
        'Datarelation für Master->Child
        Dim pc As DataColumn = dtFolders.Columns("ID")
        Dim cc As DataColumn = dtFiles.Columns("FolderID")
        dsFoldersFiles.Relations.Add("FoldersFiles", pc, cc)
 
        'Parent-Child-Koordination
        bsFolders.DataSource = dsFoldersFiles
        bsFolders.DataMember = "Folders"
 
        bsFiles.DataMember = "FoldersFiles"
        bsFiles.DataSource = bsFolders
 
        'nach Belieben .....
        dgv_Folders.Columns("ID").Visible = False
        dgv_Files.Columns("ID").Visible = False
        dgv_Files.Columns("FolderID").Visible = False
    End Function
Ich möchte den User mittels Popupmenu erlauben, die einzelnen Folder und Files umzubenennen.
Dazu möchte ich dann den entsprechenden Spalteneintrag mit readonly=false freigeben.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 18:37

P.S.
Die zwei API-Funktionen

    Private Sub FindAllFiles(ByVal folder As String, ByVal pattern As String, _
      ByRef files As List(Of String))
 
        Dim w32data As New WIN32_FIND_DATA
        Dim Handle As System.IntPtr = FindFirstFile(Path.Combine(folder,
          "*.*"), w32data)
        If Handle <> CType(INVALID_HANDLE_VALUE, System.IntPtr) Then
            Dim Search As Boolean = True
            Do
                'Handelt es sich um ein Verzeichnis? 
                If Not (w32data.sfileAttributes And FILE_ATTRIBUTE_DIRECTORY) =
                      FILE_ATTRIBUTE_DIRECTORY Then
                    If w32data.fileName Like pattern Then
                        files.Add(Path.Combine(folder, w32data.fileName))
                    End If
                End If
            Loop Until FindNextFile(Handle, w32data) = CType(False,
              System.IntPtr)
 
            'handle schliessen
            FindClose(Handle)
        End If
    End Sub
 
 
    Private Sub FindAllDirs(ByVal folder As String, ByVal pattern As String, _
      ByRef files As List(Of String))
 
        Dim w32data As New WIN32_FIND_DATA
        Dim Handle As System.IntPtr = FindFirstFile(Path.Combine(folder,
              "*.*"), w32data)
        If Handle <> CType(INVALID_HANDLE_VALUE, System.IntPtr) Then
            Dim Search As Boolean = True
            Do
                'Handelt es sich um ein Verzeichnis? 
                If (w32data.sfileAttributes And FILE_ATTRIBUTE_DIRECTORY) =
                          FILE_ATTRIBUTE_DIRECTORY Then
                    'Verzeichnisnamen ermitteln und für den späteren rekursiven 
                    ' Aufruf speichern 
                    If w32data.fileName <> "." And w32data.fileName <> ".." Then
                        files.Add(Path.Combine(folder, w32data.fileName))
                    End If
                End If
            Loop Until FindNextFile(Handle, w32data) = CType(False,
                  System.IntPtr)
 
            'handle schliessen
            FindClose(Handle)
        End If
    End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 19:57

Ah,
mein Fehler...
die Zuweisung, die in der Funktion in der 4. Zeile stand
Dim DateiListe As New List(Of String)
muss natürlich in die Verzeichnis-Einleseschleife direkt vor die Dateien-Einleseschleife, damit die Dateiliste beim Eintreten der inneren Schleife auch tatsächlich leer ist.

Jetzt habe ich zwei funktionierende Grids, die nur wirklich zugreifbare Dateien und Ordner beinhalten und kann so erst mal weiterwursteln und meine weitere Datenanbindung an die Grids wieder ranknoten.

Danke Dir nochmal, Manfred.
Du warst mir da eine echt grosse Hilfe!

Werde sicher bald auf das nächste Problem stossen

Beitrag wurde zuletzt am 02.01.23 um 19:58:37 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 21:38

P.S.

Das Einfärben der Spaltenköpfe bekomme ich nicht hin
    dgvFolders.Columns("ID").HeaderCell.Style.BackColor = Color.Yellow
bzw. bei mir
    dgv_Folders.Columns("ID").HeaderCell.Style.BackColor = Color.FromKnownColor( _
      KnownColor.ControlDark)
Die bleiben aber weiss.

Das Ändern der Schriftart/Grösse und das Verstecken der RowHeader-Spalte klappt.

Wie bekomme ich nun aus den Tabellen die angeklickten Pfade heraus?
Das müsste doch funktionieren.
Ich kann diese zwar auch aus den selektierten Zeilen herausrechnen, aber Du hast ja geschrieben, dass es mit den Tabellen einfacher ist.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 22:08

Mit
    Private Sub dgv_Folders_CellContentClick(sender As Object, e As _
      DataGridViewCellEventArgs) Handles dgv_Folders.CellContentClick
        Debug.Print(dtFolders.Rows(e.RowIndex)("Verzeichnis").ToString)
    End Sub
kann ich zwar den selektierten Verzeichnisnamen auslesen, aber schon inn der dtFiles klappt das nicht mehr, denn da sind ja alle Dateien aller Ordner drin gelistet.
    Private Sub dgv_Files_CellContentClick(sender As Object, e As _
      DataGridViewCellEventArgs) Handles dgv_Files.CellContentClick
        Debug.Print(dtFiles.Rows(e.RowIndex)("Filename") & dtFiles.Rows( _
        e.RowIndex)("Endung").ToString)
    End Sub
Wie komme ich denn an die entsprechenden Daten in den Tabellen?
Muss ich tatsächlich eine Funktion schreiben, die mir anhand der Indexe den passenden Filenamen aus der Tabelle sucht und diesen dann zurückgibt?
Dies wäre im Moment meine einzige Idee.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 22:31

Oh sorry, habe Dein Post von gestern 11:14
Private Sub dgvFiles_RowHeaderMouseClick(sender As Object,
          e As DataGridViewCellMouseEventArgs) Handles _
            dgvFiles.RowHeaderMouseClick
 
        'Anzeige einer Textdatei beim Click auf einen Zeilenkopf im Grid mit 
        'den Dateinamen
 
        'an GridView gebundene Bindingsource
        Dim rowview As DataRowView = bsFiles(e.RowIndex)
 
        'Datarelation verwenden
        'Datarowview weist die Datarow der gebundenen Tabelle (row-Eigenschaft)  
        Dim parentrow = rowview.Row.GetParentRow("FoldersFiles")
        Dim subfoldername As String = parentrow("Subfolder")
 
        'Den kompletten Pfad der Datei zusammenstellen
        Dim filename As String = IO.Path.Combine(basefolder, 
                                  subfoldername, rowview.Row( _
                                    "Filename").ToString)
 
        Try
            tboFileContent.Text = IO.File.ReadAllText(filename)
            Me.Text = IO.Path.GetFileName(filename)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
 
End Sub
nicht gesehen.
Das ist ja genau das, was ich suchte.

Aber hier lästert VS mein Anklicken eines RowHeaders in der dgv_Files:
"System.ArgumentException: Spalte 'Subfolder' gehört nicht zu Tabelle Folders"
in der Zeile
Dim subfoldername As String = parentrow("Subfolder")
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 02.01.23 22:48

Auch gelöst...
Die Spalte "Subfolder" heisst bei mir "Gruppe"
Damit werkelt es prima.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 02.01.23 22:53

Hallo!

Das ist der Standardstyle für alle Spalten einer Tabelle (Default):
dgvFolders.ColumnHeadersDefaultCellStyle.BackColor = Color.Green

Diese allgemeine Einstellung kann für einzelne Spalten überschrieben werden:
dgvFolders.Columns("ID").HeaderCell.Style.BackColor = Color.FromKnownColor(KnownColor.ControlDark)

Das funktioniert.
Welche anderen Einstellungen am Grid hast Du vorgenommen?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 15:34

Hi Manfred,

lieben Dank für Deine Mühe!

Ich habe das DGV von Hand im Designer aufgezogen und nicht wie in Deinem Script im Code.
In meinem DGV werden die Spaltenköpfe der angeklickten Zellen in hellblauem Background markiert.
Wahrscheinlich werden deshalb die Farbzuordnungen unterdrückt.
In den Eigenschaften der dgv_Files und dgv_Folders finde ich nichts, um diese Vorgabe zu unterdrücken.

Habe die ganze Nacht Informationen zum DGV und dessen Bedienung gesucht, nachdem mein Buch sich in dem entsprechenden Kapitel nur äusserst spartanisch darüber auslässt - leider vergeblich.
Ich trauere den Zeiten nach, wo man mit den Programmiersprachen noch 2kg Bücher dazu bekommen hat.

Dann habe ich noch ein weiteres Problem.
Eine Spalte der dvg_Files beinhaltet bei mir die Dateigrösse.
Nun möchte ich diese Grössenangaben in Bytes/KB/MB/GB/TB umgerechnet darstellen.
Das klappt auch, wenn ich diese Spalte in der dtFiles-Tabelle als String formatiere.
Aber dann kann ich diese Spalte ja nicht mehr durch Klick auf den Spaltenkopf korrekt sortieren.
Würde ich dazu eine Hidden-Spalte mit den unformatierten Grössenangaben (alles in Bytes) als Integer hinzufügen, kann ich es dann irgendwie hinbekommen, dass beim Klick auf den Spaltenkopf "Grösse"(formatiert) nach der Spalte "Grösse" (unformatiert in Bytes) sortiert wird?
Oder wie ist so was zu lösen?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 03.01.23 18:00

Hallo!

Ohne Kenntnis Deines Codes und insbesondere der Einstellungen
des Grids, kan ich keine Information zur Einfärbung der Spaltenköpfe
geben. Bisher ist mir dieses Verhalten nicht untergekommen.

Das gebundene Dataset trennt die Datenhaltung (Datatable)von der
Organisation der Daten (Bindingsource, Sortieren, Filtern, Verknüpfen)
und der Anzeige/Bearbeitung der Daten (Datagridview, User-Steuerung).

Jede dieser Ebenen erledigt bestimmte Aufgaben.

Schreibe in die Datatable deshalb die Größe der Datei als Anzahl der
Bytes - wie sie im Fileinfo-Onjekt (Length) geliefert wird.
Für die Darstellung in einer Datagridview-Spalte solltest Du Dich
für ein bestimmtes Format entscheiden. Unterschiedliche Formate
(KB/GB) in einer Spalte sind nicht zu empfehlen.

Die Umrechnung der gespeicherten Zahl von Bytes in das Anzeigeformat
im Grid erfolgt durch das dafür vorgesehene DatagridView-Event (CellFormatting).

Eine Möglichkeit wäre die Verwendung des Sort-Compare Ereignisses des Grid
für den Vergleich unterschiedlich formattierter Größenangaben.
Der Vergleich erfolgt per Code nicht nach dem formatierten Wert, sondern
nach dem zugrundeliegenden ByteWert in der Table (Zugriff durch rowview.row, siehe oben).

Alternativ kannst Du eine zusätzliche Tabellen-Spalte erstellen, die beim
Hinzufügen (Add-Methode) im dritten Parameter einen Expressionsausdruck enthält.
Diese Spalte wird nicht per Code mit Daten gefüllt, sondern der Inhalt einer Zeile
wird aus den Inhalten anderer Spalten der Zeile berechnet, gemäß der gegebenen Formel.
In Deinem Fall wäre das die gewünschte bedingte Umrechnung (String-Spalte).
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 19:00

Hi Manfred,

danke für Deine Geduld.

1. Das Spaltenkopf-Farbproblem

Ich habe es teilweise gefunden:
"EnableHeadersVisualStyle" muss auf false gesetzt werden.
Dann wird meine Farbzuordnung (hellgrau) für die Spaltenköpfe übernommen.

Allerdings wird beim ersten Klick in eine der beiden DGVs der jeweils erste sichtbare Spaltenkopf nun mit Background dunkelblau markiert und bleibt auch so markiert, selbst, wenn ich das Control verlasse.
Bekomme ich diese Markierung vielleicht auch irgendwie weg?


2. Das Formatierte Grösse anzeigen Problem

In der dgv_files soll dann z.B. stehen:
ID FolderID Dateiname Endung Grösse Änderungsdatum Erstellungsdatum Zugriffsdatum
1 1 Datei1 .txt 980 Bytes 01.01.2022 01.01.2022 01.01.2022
2 1 Datei2 .txt 1,2 KB 01.01.2022 01.01.2022 01.01.2022
3 1 Datei3 .txt 620 Bytes 01.01.2022 01.01.2022 01.01.2022
4 1 Datei4 .txt 2.4 MB 01.01.2022 01.01.2022 01.01.2022

Und wenn ich auf den Spaltenkopf "Grösse" klicke, soll die Tabelle korrekt nach der Grösse sortiert werden.

Kannst Du mir vielleicht Beispiele für die zwei von Dir genannten Optionen posten?
Hört sich beides gut an.


3. beim Anklicken der untersten leeren Spalte der dgv_Folders sollen die Inhalte der dgv_files ausser den Spaltenköpfen geleert werden, da dann ja auch kein Ordner selektiert ist, dessen Dateien angezeigt werden sollen.

Die Textbox kann ich in diesem Fall so leeren:

    Private Sub dgv_Folders_CellClick(sender As Object, e As _
      DataGridViewCellEventArgs) Handles dgv_Folders.CellClick
        If e.RowIndex = bsFolders.Count - 1 Then
            ' untere leere Zeile
            ' hier soll der Inhalt der dgv_Files geleert werden
            updateStatusFields() ' Labels in der Statuszeile updaten
            OpenFile("") ' Inhalt der Textbox leeren
        End If
    End Sub
 
 
    Private Sub dgv_Folders_CellContentClick(sender As Object, e As _
      DataGridViewCellEventArgs) Handles dgv_Folders.CellContentClick
        ' gefüllte Zeile
        If dgv_Folders.SelectedRows.Count = 1 Then
            ' eine gefüllte Zeile
            ersterEintrag()
        Else
            ' mehrere gefüllte Zeilen
            ' hier soll der Inhalt der dgv_Files geleert werden
            OpenFile("") ' Inhalt der Textbox leeren
        End If
        updateStatusFields() ' Labels in der Statuszeile updaten
    End Sub
 
    Private Sub ersterEintrag()
        Dim filename As String
        If bsFolders.Count > 0 And bsFiles.Count > 0 Then
            Dim rowview As DataRowView = bsFiles(0)
            Dim parentrow = rowview.Row.GetParentRow("FoldersFiles")
            Dim subfoldername As String = parentrow("Gruppe")
            filename = IO.Path.Combine(My.Settings.HauptPfad, subfoldername, _
              rowview.Row("Dateiname").ToString & rowview.Row( _
              "Endung").ToString)
        Else
            filename = ""
        End If
        OpenFile(filename) ' Datei in Textbox anzeigen
    End Sub
 
    Private Sub updateStatusFields()
        StatusbarLabel1.Text = "Gruppen: " & _
          dgv_Folders.SelectedRows.Count.ToString & " / " & _
          bsFolders.Count.ToString
        StatusbarLabel2.Text = "Clips: " & _
        dgv_Files.SelectedRows.Count.ToString & " / " & bsFiles.Count.ToString
    End Sub
Nur, wie leere ich die dgv_files?

4. In meinem "schlauen" Buch und auch im Web finde ich nichts, wie man die Textausrichtung der DGV-Spalten einstellen kann.
Gewünscht ist:
Spalte 0 und 1: egal, Spalte 3: Linksbündig, Spalten 4-7: Rechsbündig
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Beispiel für Formatieren und Sortieren von Byteangaben 
Autor: Manfred X
Datum: 03.01.23 19:05

Public Class frmByteFormatting
 
    Dim bsFiles As New BindingSource
    Dim WithEvents dgvFiles As New DataGridView With {.Parent = Me, .DataSource _
      = bsFiles}
    Dim dtFiles As New DataTable
 
 
    Private Sub frmByteFormatting_Load(sender As Object, e As EventArgs) _
      Handles MyBase.Load
 
        Dim basefolder As String = "G:\daten"  ' Ordner mit Dateien angeben
 
        dtFiles.Columns.Add("Filename", GetType(String))
        dtFiles.Columns.Add("Length", GetType(Integer))
 
        'Dateinamen und Länge in Table eintragen
        For Each file As String In IO.Directory.EnumerateFiles _
            (basefolder, "*.*", IO.SearchOption.TopDirectoryOnly)
 
            dtFiles.Rows.Add(IO.Path.GetFileName(file), New IO.FileInfo( _
              file).Length)
        Next file
 
        'Datenbindung
        bsFiles.DataSource = dtFiles
 
        'Grid einrichten
        dgvFiles.AllowUserToAddRows = False
 
        dgvFiles.Columns("Length").DefaultCellStyle.Alignment =
            DataGridViewContentAlignment.MiddleRight
 
    End Sub
 
 
    Private Sub dgvFiles_CellFormatting(sender As Object,
        e As DataGridViewCellFormattingEventArgs) Handles _
          dgvFiles.CellFormatting
 
        If e.ColumnIndex = 1 Then
            Dim vl As String
            Dim row As DataRow = bsFiles(e.RowIndex).row
            Dim length As Integer = CInt(row.Item("Length"))
            If length < 1024 Then
                vl = length.ToString & "  B"
            ElseIf length < 1024 * 1024 Then
                vl = CInt(length / 1024).ToString & " KB"
            Else
                vl = CInt(length / 1024 / 1024).ToString & " MB"
            End If
 
            e.Value = vl
            e.FormattingApplied = True
        End If
    End Sub
 
 
    Private Sub dgvFiles_SortCompare(sender As Object,
        e As DataGridViewSortCompareEventArgs) Handles dgvFiles.SortCompare
 
        If e.Column.Name <> "Length" Then Exit Sub
 
        Dim row1 As DataRow = bsFiles(e.RowIndex1).row
        Dim row2 As DataRow = bsFiles(e.RowIndex2).row
 
        e.SortResult = CInt(row1("Length")).CompareTo(CInt(row2("Length")))
        e.Handled = True
    End Sub
 
End Class
Statt auf Integer zu runden, kann man die Math.Round-Methode einsetzen,
um gewünschte Nachkommastellen zu erhalten. Ich empfehle das nicht.
Die Gleitkomma-Darstellung sollte dann allerdings übersichtlich formatiert
werden (Komma in allen Spalten an gleicher Stelle).

Ich weiß nicht was das Löschen der Daten für eine Funktion hat.
Die Daten stehen in der Datatable. Dort sollten die Löschungen erfolgen (Clear).

Die unterste Spalte dient dem Anfügen neuer Zeilen und ist
in Deinem Fall abzuschalten (AlloWUsersToAddRows).

Beitrag wurde zuletzt am 03.01.23 um 19:19:20 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 19:59

Zu 1.
Ich habe nun im "ColumnHeadersDefaultCellStyle" die "SelectionBackColor" auf meine für die Spaltenköpfe gewählte Hintergrundfarbe gesetzt - nun bleiben die Spaltenköpfe in der Hintergrundfarbe, auch, wenn eine Zelle angeklickt wird.

Zu 4.
            dgv_Files.Columns(2).HeaderCell.Style.Alignment = _
              DataGridViewContentAlignment.MiddleLeft
            dgv_Files.Columns(3).HeaderCell.Style.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(4).HeaderCell.Style.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(5).HeaderCell.Style.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(6).HeaderCell.Style.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(7).HeaderCell.Style.Alignment = _
            DataGridViewContentAlignment.MiddleRight
 
            dgv_Files.Columns(2).DefaultCellStyle.Alignment = _
              DataGridViewContentAlignment.MiddleLeft
            dgv_Files.Columns(3).DefaultCellStyle.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(4).DefaultCellStyle.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(5).DefaultCellStyle.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(6).DefaultCellStyle.Alignment = _
            DataGridViewContentAlignment.MiddleRight
            dgv_Files.Columns(7).DefaultCellStyle.Alignment = _
            DataGridViewContentAlignment.MiddleRight
Spaltenausrichtung klappt, Spaltenheaderausrichtung klappt nicht
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 20:24

Superklasse - Danke Dir recht sakrisch, Manfred.
Wenn ich nur auch schon so weit wäre, wie Du...

zu 2.
Wenn ich Dich recht verstehe, wird CellFormatting zwischen Tabelle und Grid geschaltet und wandelt die Einträge der Tabelle in das gewünschte, in das im Grid anzuzeigende Format um, wobei die Tabelleninhalte bsFiles unverändert bleiben?
Und mit der Funktion SortCompare ersetze ich damit die Standard-Sort-Funktion beim Anklicken der Spalte "Length", leite die Sortierung auf die Tabelle bsFiles um und sortiere nach dieser, anstatt nach der Grid-Spalte?
Und ich brauche die beiden Funktionen nur an die entsprechenden Aufrufe des Grids zu knoten?
Das ist ja genau das, was mir vorschwebte.
Mir reichen hier drei Nachkommastellen bei Dezimalbrüchen.

zu 3.
Die leere letzte Zeile kann ich verstecken, bis ein User den "Neu"-Button oder den entsprechenden Popupmenu-Eintrag auswählt.
Das ist nicht so das Problem.
Mir geht es aber darum, wenn der User mehrere Zeilen in der dgv_Folders auswählt (muss möglich sein, zur Löschung von mehreren Folders und Files auf einmal), sollte dann natürlich der Inhalt der dgv_Files geleert werden, da bei mehreren selektierten Folders die zweifelsfreie Zuordnung der Einträge in der dgv_Files zum gewählten Folder nicht mehr möglich ist.
Der Inhalt der dgv_files soll also nur angezeigt werden, wenn in der dgv_Folders exakt ein Eintrag ausgewählt ist.
Aber in den gebundenen Tabellen sollen die Einträge natürlich erhalten bleiben, da diese benötigt werden, wenn der User einen anderen Folder selektiert.

Beitrag wurde zuletzt am 03.01.23 um 20:51:54 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 20:47

Zu 2.
Funktioniert Obersuper!
Danke Dir - so langsam müssen wir uns mal über Deinen Stundenlohn unterhalten.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 20:50

P.S.
zu 4.
die Alignment-Geschichte funktioniert schon wie gepostet - habe nur den rechten Platz für die Sortierungspfeilchen vergessen.
Daher hat Rechtsbündig nicht nach Rechtsbündig ausgesehen.

Zu 3.
Ich glaube, ich lasse die User nur max. einen Folder löschen und setze die dgv_Folders auf Multiselect = false.
Dann ist das Problem beseitigt.
Und will der User tatsächlich mal mehrere Folder auf einmal löschen, kann er es ja mit dem Win-Explorer machen.

Beitrag wurde zuletzt am 03.01.23 um 20:54:20 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 03.01.23 20:55

Dir ist noch nicht klar, wie Datenbindung funktioniert.

Die Formatierung einer Zelle im Grid verändert den Inhalt der angebundenen
Datentabelle nicht.
Der Code im Eventhandler ist dafür verantwortlich, die Anzeige zu gestalten.
Es ist nicht vorgesehen/zu empfehlen, dass durch diesen Code eine Veränderung
in der Datatable vorgenommen wird.

bsFiles enthält einen Zeiger auf die Tabelle dtFiles, aber selbst keine Daten.
Das Sortieren der Datensätze wirkt sich nicht auf die Datatable aus, sondern
auf den Zeiger, der von bsFiles auf Datensätze der Tabelle zeigt.

Der integrierte Sortieralgorithmus muss jeweils zwei Sätze miteinander vergleichen.
Diese Vergleiche kann man in SortCompare-Event des Grid per Code durchführen.
Im Beispiel hole ich die gespeicherten Byte-Angaben aus je zwei Zeilen, vergleiche
sie durch die Integer-Compare-Methode und liefere das Ergebnis dieses Vergleichs
an den e-Parameter zurück. Diese Ergebnis nutzt der Sortieralgorithmus für die
Anordnung der Datensätze (in bsFiles und damit im Grid).

Das Grid "dgvFolders" sollte keine Mehrfachauswahl zulassen.
dgvFolders.MultiSelect = False
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 03.01.23 21:13

Ja so habe ich es auch gemeint - Du hast es nur deutlicher und schöner beschrieben.

Die Grid ist nur der Spiegel der Tabellen-Auszüge im Hintergrund, in der ich sehen kann, was sich in den Tabellenteilen befindet.

Das CellFormatting ist ein Interface, das die anzuzeigende Tabelleninhalte in das gewünschte, in der Grid auszugebende Format umbaut.
Soweit verständlich.

Nur warum dann das SortCompare für die Grösse? in der Tabelle sind die Grössen ja bereits im Int-Format und damit eigentlich sortierbar.
Diesen Punkt vestehe ich nicht.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 03.01.23 22:02

Das siehst Du richtig. Bei gebundenen Datenquellen kann auf die
Eigenschaft (geeignete Interface-Implementierung vorausgesetzt) der
Datenquell-Spalte zugegriffen werden. Das SortCompare-Event wird in
dem Fall nicht ausgelöst.
(Mein Beispiel bezieht sich sinngemäß auf das Sortieren in
nicht gebundenen Grids.)

Beitrag wurde zuletzt am 03.01.23 um 22:07:18 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 04.01.23 21:58

Hi Manfred,
danke Dir!
Baue gerade das Drumherum um die GridViews wieder zusammen.
Bis jetzt sieht es prima aus - und viel besser, als mit den ListViews.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 10.01.23 19:10

Hi Manfred,

ich habe jetzt tagelang probiert und komme einfach nicht weiter.

1. Wenn ich neue Verzeichnisse in die DGV_Folders hinzufügen will, wie mache ich das mit der entsprechenden Erweiterung der gebundenen Tabelle?

2. Wie code ich überhaupt bei "Neues Verzeichnis" die mit "dgv_Folders.AllowUserToAddRows = true" freigebene untere Leerzeile, in welche ich den neuen Verzeichnisnamen eingeben möchte?


Das funktioniert schon mal

    Private Sub mnu_Ordner_Neu_Click(sender As Object, e As EventArgs) Handles _
      mnu_Ordner_Neu.Click
        ' Anzeige untere Leerzeile
        dgv_Folders.AllowUserToAddRows = True
        dgv_Folders.ReadOnly = False
        dgv_Folders.FirstDisplayedScrollingRowIndex = dgv_Folders.Rows.Count - 1
        dgv_Folders.Rows(dgv_Folders.Rows.Count - 1).Cells(1).Selected = True
        dgv_Folders.BeginEdit(True)
    End Sub
Hier bin ich noch am werkeln:

    Private Sub dgv_Folders_CellEndEdit(sender As Object, e As _
      DataGridViewCellEventArgs) Handles dgv_Folders.CellEndEdit
        'Dim nVerz As String
        ' Prüfen, ob nicht leer
        'If dgv_Folders.Rows(dgv_Folders.Rows.Count - 1).Cells(1).Value <> "" Then
        '    ' Zelle hat Inhalt
        '    nVerz = (aktivesArchivPfad & dgv_Folders.Rows( 
        ' dgv_Folders.Rows.Count - 2).Cells(1).Value)
        '    ' Prüfen, ob Verzeichnis bereits existiert
        '    If IO.Directory.Exists(nVerz) = True Then
        '        ' Verzeichnis existiert bereits
        '        MsgBox("Verzeichnis " & Chr(34) & nVerz & Chr(34) & "" & _
          "existiert bereits")
        '        dgv_Folders.Rows(dgv_Folders.Rows.Count - 1).Cells(1).Value = 
        ' ""
        '    Else
        '        ' Verzeichnis existiert noch nicht  
        '        My.Computer.FileSystem.CreateDirectory(nVerz)
        '    End If
        'End If
        'CreateFilesAndFolders()
    End Sub
Hier bekomme ich einen Fehler, da ich im RowLeave keine Zeilen entfernen darf:

    Private Sub dgv_Folders_RowLeave(sender As Object, e As _
      DataGridViewCellEventArgs) Handles dgv_Folders.RowLeave
        ' Prüfen, ob letzte Zeile
        If dgv_Folders.CurrentCell.RowIndex = dgv_Folders.Rows.Count - 1 Then
            dgv_Folders.AllowUserToAddRows = False
            ' Prüfen, ob leer
            If dgv_Folders.Rows(dgv_Folders.Rows.Count - 1).Cells( _
              1).Value.ToString = "" Then
                dgv_Folders.Rows.Remove(dgv_Folders.Rows(dgv_Folders.Rows.Count _
                - 1))
            End If
        End If
        dgv_Folders.ReadOnly = True
    End Sub
Muss ich nach Neu/Rename/Remove von Verzeichnissen jedesmal die Funktion "CreateFilesAndFolders()" aufrufen, oder kann ich diese Änderungen auch direkt in der gebundenen Tabelle des dgv_Folders vornehmen?

3. Woran ich mir auch die Zähne ausbeisse, Deine Function "CreateFilesAndFolders()" funktioniert ja perfekt.
Aber wie mache ich es, wenn ich nur die im dgv_Files angezeigte Dateiliste der an die dgv_Files gebundenen Tabelle aktualisieren lassen will?
Denn wenn ich eine neue Datei anlegen lasse, diese umbenenne oder lösche (hierbei warten dann dieselben Probleme mit dem Ändern der gebundenen Tabelle), muss ja nur die Dateiliste des gewählten und angezeigten Verzeichnisses geupdatet werden.
Würde ich hier jedesmal Deine Function "CreateFilesAndFolders()" aufrufen, würde das bei vielen im Archiv enthaltenen Verzeichnissen und Dateien zu lange dauern.

5. Gibt es denn nicht irgendwelche gute Bücher oder Webseiten, die so was erklären - vor allem mit den gebundenen Tabellen usw.?
Meine VB.net-Bücher lassen sich so gar nicht über diese Themen aus. Und im Web bin ich auch nicht fündig geworden.

Beste Grüsse
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 11.01.23 12:10

Hallo!

Du hast Dir eine umfangreiche Aufgabe vorgenommen.

Im Filesystem kommt es durch Programme oft zu Änderungen.
Setze deshalb einen Filesystemwatcher ein und übertrage die
gemeldeten Änderungen (Löschen, Umbennenen, Inhalt ändern,
Verschieben, Neu anlegen) in die Tabelle.

Beim Editieren einer Zelle durch den Benutzer ist zunächst im
BeginEdit-Event der bisherige Wert zu speichern.
Beim EndEdit kann dann versucht werden, die Änderung des Benutzers
an der Tabelle in das Filesystem zu übertragen.
Falls das scheitert (Exception) muss der alte Wert wieder in die
Tabelle eingetragen werden.

Während des Editierens sollten die erforderlichen Aktualisierungen
der Tabelle wegen der Meldungen durch den Watcher zwischengespeichert
und erst nach Abschluß des Editierens nachgetragen werden.

Ich empfehle, zunächst die Verwendung des Filesystemwatchers zur
Aktualisierung der Tabelle gemäß dessen Meldungen zu programmieren.
Ohne diese kontinuierliche Koordination zwischen Tabellen und Dateisystem
dürfte Dein Programm keinen großen Nutzen bringen, vermute ich.

Die Aktualisierungen der Tabelle könnte man in einen Hintergrundprozess
auslagern und zwischen jeweils zwei Instanzen der Tabelle wechseln (eine wird
angezeigt, während die andere neu gefüllt wird. Nach dem Füllen Wechsel der
Tabelle, die an der Bindingsource hängt).

Das war ein grober Überblick über die vermuteten Aufgaben Deines Programms.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 11.01.23 18:18

Hi Manfred,

danke Dir für Deine Hilfe

Du schlägst also vor, die Änderungen (Neue Datei/Ordner, Löschen von Ordnern/Dateien, Umbenennen von Ordnern/Dateien) nicht parallel in den Tabellen und im Dateisystem zu ändern, sondern ausschliesslich im Dateisystem und bei Änderung via Filewatcher die Tabellen neu einzulesen.
Habe ich Dich da korrekt verstanden?

Einen Filesystemwatcher hatte ich eh geplant - allerdings eigentlich nur für das "Netzwerk-Archiv".
Mein Proggi wird dann umschaltbar ein "Lokales Archiv" und ein "Netzwerk-Archiv" anzeigen.
Diese Archive bestehen ja aus den Ordnern 1. Ebene im jeweiligen Archiv-Stammverzeichnis und den in diesen Ordnern enthaltenen Dateien.

Da das Netzwerk-Archiv auch von anderen Usern benutzt werden wird, muss ich da ohnehin eine Überwachung haben, ob Änderungen im Dateisystem vorliegen, welche es erfordern, die Tabelle dtFolders und die Tabelle dtFiles neu einzulesen.
Wenn das gerade angezeigte Dokument zwischenzeitlich von Dritten geändert wurde, muss ich auch eine Warnung ausgeben lassen und dem User anbieten, seine bearbeitete Datei unter einem anderen Namen zu speichern "Dateiname+(Kopie).Extension".

Um nur die dtFiles zu aktualisieren, denke ich, dass das etwa so gemacht werden müsste:
- Alle Einträge in der dtFiles mit FolderID des aktuell gewählten Verzeichnisses entfernen
- Alle Dateien im aktuellen Folder in der dtFiles neu hinzufügen, wobei die FolderID vom aktuellen Folder übernommen und die jeweilige FileID immer +1 der höchsten bestehenden FileID werden muss.
Dann habe ich zwar eine Lücke in der Nummerierung der FileIDs, aber das sollte ja der Funktion keinen Abbruch tun.

Oder ist das Mist und ich muss immer die dtFolder und dtFiles gleichzeitig neu einlesen lassen?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 11.01.23 18:49

Ist es denn praktikabel zum Neuanlegen von Ordnern und Dateien die unterste leere Grid-Zeile anzuzeigen und da den Neueintrag reinschreiben zu lassen? Da finde ich keine Anleitung, wie man das codet.
Alternativ könnte ich auch eine Eingabe-Form bauen und den Benutzer da drin die neuen Namen eingeben lassen.
Wie macht man sowas am Besten und konform zu anderen Programmen?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 11.01.23 18:55

Das Herumfuhrwerken im Dateisystem ist eine komplexe Aufgabe.
Ein Teil-Beispiel zur Verdeutlichung.

 Dim oldfoldername As String = Nothing
 
 
 Private Sub dgvFolders_CellBeginEdit(sender As Object,
    e As DataGridViewCellCancelEventArgs) Handles dgvFolders.CellBeginEdit
 
        If e.ColumnIndex <> 1 Then Exit Sub
 
        Dim obj As Object = bsfolders(e.RowIndex).Row(e.ColumnIndex)
        If IsDBNull(obj) Then
            oldfoldername = Nothing
        Else
            oldfoldername = obj.ToString
            If Not IO.Directory.Exists(IO.Path.Combine _
                                   (basefolder, oldfoldername)) Then
                MsgBox("Der Ordner " & oldfoldername & " existiert nicht")
            End If
        End If
 
  End Sub
 
 
  Private Sub dgvFolders_CellEndEdit(sender As Object,
          e As DataGridViewCellEventArgs) Handles dgvFolders.CellEndEdit
 
        If e.ColumnIndex <> 1 Then Exit Sub
 
        Dim rowview As DataRowView = bsfolders(e.RowIndex)
        Dim obj As Object = rowview.Row(e.ColumnIndex)
        If IsDBNull(obj) Then Exit Sub
        Dim newfoldername As String = obj.ToString
        If newfoldername.ToLower = oldfilename.ToLower Then Exit Sub
 
        If Not CheckFoldername(newfoldername) Then
            rowview.Row(e.ColumnIndex) = oldfoldername
            MsgBox("Unzulässiges Zeichen im Verzeichnisnamen")
            Exit Sub
        End If
 
        If IO.Directory.Exists(IO.Path.Combine(basefolder, newfoldername)) Then
            MsgBox("Dieses Verzeichnis existiert bereits")
            'Einbauen: falls Oldfoldername = Nothing DBNull.Value setzen
            rowview.Row(e.ColumnIndex) = oldfoldername
            Exit Sub
        End If
 
        If oldfoldername IsNot Nothing Then
            oldfoldername = IO.Path.Combine(basefolder, oldfoldername)
            If IO.Directory.Exists(oldfoldername) Then
                'Bestehenden Ordner umbenennen
                Try
                    My.Computer.FileSystem.RenameDirectory _
                            (oldfoldername, newfoldername)
                Catch ex As Exception
                    MsgBox(ex.Message)
                    rowview.Row(e.ColumnIndex) = oldfoldername
                End Try
            Else
                MsgBox("Der Ordner " & oldfoldername & " existiert nicht")
                rowview.Row(e.ColumnIndex) = DBNull.Value
            End If
        Else
            'Neuer Ordner wird erstellt
            newfoldername = IO.Path.Combine(basefolder, newfoldername)
            Try
                IO.Directory.CreateDirectory(newfoldername)
            Catch ex As Exception
                MsgBox(ex.Message)
                rowview.Row(e.ColumnIndex) = DBNull.Value
            End Try
        End If
  End Sub
 
 
  Private Function CheckFoldername(fn As String) As Boolean
        If String.IsNullOrWhiteSpace(fn) Then Return False
        Dim ivc() As Char = IO.Path.GetInvalidPathChars
        For i As Integer = 0 To fn.Length - 1
            If Array.IndexOf(ivc, fn(i)) >= 0 Then Return False
        Next i
        Return True
  End Function


Beitrag wurde zuletzt am 11.01.23 um 19:10:10 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 11.01.23 19:07

Der Filesystemwatcher meldet jede einzelne Änderung im
Datei-System, falls der Änderungs-Typ beim Watcher
angefordert worden ist (NotifyFilter).
Du musst immer nur die Tabellen-Zeile(n) anpassen, auf die
sich die vom Watcher mitgeteilte Änderung bezieht
(Created, Renamed, Deleted, Changed).

Beim Created-Ereignis muss eine neue Zeile für
die neue Datei oder den neuen Ordner erstellt werden.
Beim Renamed-Ereignis ist der neue Name in die
bereits vorhandene Tabellen-Zeile einzutragen.
Beim Deleted-Event ist die betroffene Datei-Zeile zu löschen.
Beim Löschen eines Ordners müssen zunächst die darin
befindlichen Dateien in der File-Tabelle gelöscht werden.
Beim Changed-Ereignis ist das Io.Fileinfo/Io.DirectoryInfo
abzufragen und neue Angaben sind in den zugehörigen Tabellen-
Zeilen einzutragen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 11.01.23 20:03

Wow, danke Dir!

Zumindest der Weg ist nun einigermassen klar.
Allerdings die Durchführung...
Da muss ich noch viel recherchieren.

Wenn ich Dein Script recht verstehe, ist für das ganze Grid ReadOnly auf False und allowUsertoAddRows = true gesetzt?
So, dass mit den drei Subs Umbenennen und Neu anlegen von Einträgen möglich ist.
Incl der Übernahme der Änderungen in das Dateisystem.

Das mit dem FileSystemWatcher muss ich erst noch recherchieren, wie dieser benutzt wird.
Meine App, um deren Aktualisierung/Neuentwicklung von VB6 auf VB.net es hier geht, hatte nur ein lokales Archiv - da brauchte ich noch keine Dateisystemüberwachung.
Aber wenn ich das Programm schon neu entwickle, soll es ja auch an die aktuellen Erfordernisse angepasst werden.


Was meinst Du mit:
 'Einbauen: falls Oldfoldername = Nothing DBNull.Value setzen


Beitrag wurde zuletzt am 11.01.23 um 20:05:23 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Manfred X
Datum: 11.01.23 20:23

Wenn eine neue Zelle entsteht (leer), ist dort DBNull.Value eingetragen.
Abgefragt wird das mit der IsDBNull-Methode.

Eine String-Variable kann diesen Wert nicht aufnehmen. Der String wird
von mir in dem Fall auf Nothing gesetzt (BeginEdit).
Beim Verwerfen der Benutzereingabe ist die Angabe in der Zelle
wieder auf den alten Wert zu setzen.
Falls dieser alte Wert "Nothing" ist (String.isnullorempty),
sollte DBNull.value eingetragen werden.

Edit:
If newfoldername.ToLower = oldfoldername.ToLower Then Exit Sub

Beitrag wurde zuletzt am 11.01.23 um 20:26:12 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 11.01.23 20:39

Ah ja, merci vielmals.

Bin gerade noch am Drumherum coden.
Aber bald komme ich dann an die Changes in der dgv_Folders und dgv_Files.
Dann teste ich Dein Script.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: ListView Markierung der Selektion immer anzeigen... 
Autor: Dideldum
Datum: 20.03.23 17:05

Hi Manfred,
perfekte Funktion dank Deiner Hilfe - habe inzwischen Deine Scripts umgebaut und in mein Projekt eingebaut.
Und was soll ich sagen?
Es funktioniert genau so, wie ich es haben wollte.
Allerdings habe ich Schaltflächen für Neu und Umbenennen.
Da musste ich Deine Scripts ensprechend ummoddeln.
Danke nochmal recht sakrisch für Deine Hilfe!
Beste Grüsse
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel