【问题标题】:.NET Delete actual files from listbox.NET 从列表框中删除实际文件
【发布时间】:2017-09-30 13:29:58
【问题描述】:

此代码旨在在从系统中选择文件时从系统中删除实际文件:

Dim file As String()
file = System.IO.Directory.GetFiles("C:\Users\User\Desktop", "lalala.txt", IO.SearchOption.AllDirectories)
If ListBox1.SelectedIndex = -1 Then
    MsgBox("No files selected")
Else
    System.IO.File.Delete(ListBox1.Items(ListBox1.SelectedIndex).ToString())
    ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
End If

但是,只有列表框中的项目被删除。实际文件仍然存在。我不确定应该将file 放入删除函数的哪个位置。

我提到了this,但它对我没有帮助。

________更新________

我发现哪里出错了:这是因为只有文件名被添加到列表框中:

ListBox1.Items.Add(Path.GetFileName(fileFound))

而不是Path.GetFullPath

无论如何,我可以只删除带有GetFileName 的文件吗?

【问题讨论】:

    标签: vb.net listbox delete-file


    【解决方案1】:

    如您所见,问题在于仅文件名不足以删除文件。您还需要文件的完整路径。因此,您需要某种方式来存储整个路径,但只显示文件名。这也很重要,因为在不同的目录中可能有两个(或更多)同名文件。

    ListBox 可以将其Datasource 属性设置为显示来自“实现 IList 或 IListSource 接口的对象,例如 DataSet 或 Array”的项目。

    然后设置DisplayMemberValueMember 属性来告诉它要显示什么以及作为值给出什么。

    例如,我创建了一个名为“FileItem”的类,它具有完整文件名的属性以及您想要显示的任何内容,用“FileItem”的实例填充了一个列表,并告诉 ListBox1 显示它:

    Imports System.IO
    
    Public Class Form1
    
        Class FileItem
            Property FullName As String
            Property DisplayedName As String
    
            Public Sub New(filename As String)
                Me.FullName = filename
                Me.DisplayedName = Path.GetFileNameWithoutExtension(filename)
            End Sub
    
        End Class
    
        Private Sub PopulateDeletionList(dir As String, filter As String)
            Dim files = Directory.EnumerateFiles(dir, filter, SearchOption.AllDirectories)
            Dim fileNames = files.Select(Function(s) New FileItem(s)).ToList()
            Dim bs As New BindingSource With {.DataSource = fileNames}
            ListBox1.DataSource = bs
            ListBox1.DisplayMember = "DisplayedName"
            ListBox1.ValueMember = "FullName"
    
        End Sub
    
        Private Sub ListBox1_Click(sender As Object, e As EventArgs) Handles ListBox1.Click
            Dim lb = DirectCast(sender, ListBox)
            Dim sel = lb.SelectedIndex
            If sel >= 0 Then
                Dim fileToDelete = CStr(lb.SelectedValue)
                Dim choice = MessageBox.Show("Do you really want to delete " & fileToDelete, "Confirm file delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                If choice = DialogResult.Yes Then
                    Try
                        File.Delete(fileToDelete)
                        lb.DataSource.RemoveAt(sel)
                    Catch ex As Exception
                        MessageBox.Show("Could not delete " & fileToDelete & " because " & ex.Message)
                    End Try
                End If
            End If
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            PopulateDeletionList("C:\temp", "*.txt")
    
        End Sub
    
    End Class
    

    已编辑 我忘记从 ListBox 中删除该项目。为此,它需要通过 BindingSource 绑定到 DataSource。

    额外功能 鉴于可能有多个同名文件,您可能需要在列表框项目中添加一个工具提示,以便您可以看到它所在的目录。请参阅@ 987654325@ 用于只需要稍作调整即可工作的实现,例如:

    Dim toolTip As ToolTip = New ToolTip()
    ' ...
    Private Sub ListBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles ListBox1.MouseMove
        Dim lb = DirectCast(sender, ListBox)
        Dim index As Integer = lb.IndexFromPoint(e.Location)
        If (index >= 0 AndAlso index < ListBox1.Items.Count) Then
            Dim desiredTooltip = DirectCast(lb.Items(index), FileItem).FullName
            If (toolTip.GetToolTip(lb) <> desiredTooltip) Then
                toolTip.SetToolTip(lb, desiredTooltip)
            End If
        End If
    End Sub
    

    【讨论】:

      【解决方案2】:

      最简单(且可靠)的解决方案是创建自定义数据类型并将其添加到 ListBox

      通过覆盖ToString() 方法,您可以使其仅显示文件名,而后端对象仍包含完整路径。

      Public Structure FileEntry
          Public FullPath As String 'A variable holding the full path to the file.
      
          'Overriding the ToString() method, making it only return the file name.
          Public Overrides Function ToString() As String
              Return System.IO.Path.GetFileName(Me.FullPath)
          End Function
      
          Public Sub New(ByVal Path As String)
              Me.FullPath = Path
          End Sub
      End Structure
      

      现在,无论何时您想为ListBox 添加路径,都必须添加FileEntry 结构的新实例,而不是常规字符串:

      ListBox1.Items.Add(New FileEntry(fileFound))
      

      要删除,只需将当前选定的项目转换为FileEntry,然后将其FullPath 传递给File.Delete() 方法。

      Dim Entry As FileEntry = DirectCast(ListBox1.Items(ListBox1.SelectedIndex), FileEntry)
      System.IO.File.Delete(Entry.FullPath)
      

      注意:为此每个列表框中的项目必须是FileEntry

      在线测试:https://dotnetfiddle.net/x2FuV3(请原谅格式,DotNetFiddle 在手机上不太好用)

      文档:

      【讨论】:

      • ... 将覆盖 ToString 函数与显示的内容联系起来的一点是,当未设置 DataSource 时,ListBox 在其 ObjectCollection 中的对象上调用 ToString。
      【解决方案3】:

      您可以使用 Path.Combine。

      由于您要在 C:\Users\User\Desktop 中搜索,您可以这样做来删除:

      System.IO.File.Delete(Path.COmbine("C:\Users\User\Desktop",ListBox1.Items(ListBox1.SelectedIndex).ToString())
      

      在这里,"C:\Users\User\Desktop" 和所选索引的文本将组合成一条路径。


      编辑:
      我明白了,您只想在文本框中显示文件名,但也想从系统中删除文件但不能这样做,对吗?

      你可以这样做:
      放置两个列表框,当您将文件添加到列表框 1 时,将其路径放入列表框 2,其可见性将为 False,这意味着它不会在运行时显示。

      执行此操作时,在列表框1 中选择项目时,使用 path.combine 创建路径通过添加具有相同索引号的列表中的文件名和路径。

      类似这样的:

          System.IO.File.Delete(path.combine(ListBox1.Items(ListBox1.SelectedIndex).ToString(), ListBox2.Items(ListBox1.SelectedIndex).ToString())
      

      【讨论】:

      • 嗨 Subaz,显示的文件可能在 C:\Users\User\Desktop 的子文件夹中,我怎样才能使它工作?谢谢!
      猜你喜欢
      • 2016-07-12
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 2012-02-23
      • 2022-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多