繁体   English   中英

如何在 C# 中使用 ListView 模拟文件浏览器?

[英]How to simulate a file explorer using ListView in c#?

我对 C# 和 Windows 窗体编程很陌生。 我想创建一个简单的 Windows 窗体,它有一个最初填充一些项目的 ListView。 然后,如果我双击一个项目,我想显示其他一些子项目。 显然,顶部会有一个“...”项将我带到父项。 有人可以帮我写这个简单的窗体吗?

ps 我不是很熟悉 C# Windows 窗体应用程序架构(Form.Designer.cs、Form1、Program.cs 等)

如果您想使用 ListView,您可以在双击目录时填充它。

你需要的是

  1. 双击事件
  2. 目录信息
  3. 文件信息

在编写 Windows 窗体应用程序时,您应该考虑将业务逻辑与视图逻辑分开,这里的关键字是Model view controllerModel View Presenter

让我们开始

我会创建一个 DirectoryController 类来处理你的一些逻辑。 您的 Forms 类可以处理视图逻辑,然后例如双击事件。

您可以创建一个生成 ImageList 的方法,以便您可以在 ListView 中使用它来为您的文件或目录提供正确的图像

private static ImageList GetFolderImageList()
{
    Image folderImg = Image.FromFile(@"C:\Windows\WinSxS\amd64_microsoft-windows-printing-fdprint_31bf3856ad364e35_6.3.9600.17415_none_493b0b9e590044a1\folder.ico");
    ImageList imgList = new ImageList();
    imgList.Images.Add(folderImg);
    return imgList;
}

我使用了 Windows 目录中的图像,以便它最初可以工作。 但是,当您的 ListView 中有目录时,您可以使用要显示的图像。 顺便说一下,这只会演示如何处理目录而不是文件,但从这一点来看,您应该能够自己处理文件。

创建 ImageList 后,您可以创建初始化 ListView。

    private void InitializeListView(ImageList imgList)
    {
        lvExplorer.DoubleClick += new System.EventHandler(this.lvExplorer_DoubleClick);
        lvExplorer.SmallImageList = imgList;
        lvExplorer.LargeImageList = imgList;
    }

我的 ListView 被命名为 lvExplorer,我已经将它添加到设计器中的 Windows 窗体中。 我使用 Dockstyle 来填充整个表单。

在此处输入图片说明

使用这两个函数,您应该能够初始化 ListView。

现在您需要填充 ListView。

private void ShowDirectoriesInListView(string path)
{
    DirectoryInfo info = new DirectoryInfo(path);

    DirectoryInfo parent = info.Parent;
    if (parent != null) 
    {
        lvExplorer.Items.Add(new System.Windows.Forms.ListViewItem("...", 0));
    }

    foreach (DirectoryInfo dInfo in info.GetDirectories())
    {
        lvExplorer.Items.Add(new System.Windows.Forms.ListViewItem(dInfo.Name, 0));
    }
}

使用 ShowDirectoriesInListView 方法,您可以将目录添加到 ListView。 path 参数是您要显示的目录。 如果目录有父目录,我们添加“...”目录。 根目录通常没有父目录,因此我们不会添加它。

现在让我们来看看我们如何获取我们传递给 ShowDirectoriesInListView 方法的目录。

如前所述,我们想从业务逻辑中拆分视图 所以我创建了一个控制器类

class DirectoryController
{
    private string _currentDirectory;

    public DirectoryController(string beginDirectory) 
    {
        _currentDirectory = beginDirectory;
    }

    public string AddDirectoryAndGetPath(string path)
    {
        if (path.Equals("..."))
        {
            int lastIndex = _currentDirectory.Length;
            if (_currentDirectory.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                lastIndex = _currentDirectory.LastIndexOf(Path.DirectorySeparatorChar);
                _currentDirectory = _currentDirectory.Remove(lastIndex);
            }
            lastIndex = _currentDirectory.LastIndexOf(Path.DirectorySeparatorChar) + 1;
            _currentDirectory = _currentDirectory.Remove(lastIndex);

        }
        else
        {
            _currentDirectory = string.Format("{0}{1}{2}", _currentDirectory, path, Path.DirectorySeparatorChar);
        }
        return _currentDirectory;
    }
}

这个类最重要的功能是 AddDirectoryAndGetPath 方法。 如果该方法获取内容为“...”的字符串,我们从当前目录中删除最后一个目录名称,否则我们将添加它。

现在回到双击事件。 您确实在 InitializeListView 方法中设置了一个事件处理程序

被调用的方法应该与您作为参数传递给 EventHandler 的构造函数的方法具有相同的名称。

private void lvExplorer_DoubleClick(object sender, EventArgs e)
{
    string path = lvExplorer.SelectedItems[0].Text;
    OpenDirectory(path);
}

当一个项目被双击时,该方法被调用并且 SelectedItems 列表应该填充一个项目。 我应该在这里提到, selectedItems 数组中可能有多个项目或没有项目,因此请在此方法中添加一些错误处理或将 ListView 的MultiSelect属性设置为false 所选 Item 的 text 属性填充了您单击的 Item 的目录名称,因为我们在ShowDirectoriesInListView方法中使用了目录名称。

然后调用 OpenDirectory 方法,该方法清除 ListView 并将所选目录的所有目录添加到其中。

private void OpenDirectory(string path)
{
    try 
    {
        lvExplorer.Items.Clear();
        string newPath = _controller.AddDirectoryAndGetPath(path);
        ShowDirectoriesInListView(newPath);
    }
    catch (Exception ex) 
    {
        MessageBox.Show(ex.Message);
    }
}

最后,您将拥有一个像这样的 Windows 窗体类

public partial class Form1 : Form
{
private DirectoryController _controller;

public Form1()
{
    InitializeComponent();
    ImageList imgList = GetFolderImageList();
    InitializeListView(imgList);
    _controller = new DirectoryController("C:");
    OpenDirectory("");
}

private void InitializeListView(ImageList imgList)
{
    lvExplorer.DoubleClick += new System.EventHandler(this.lvExplorer_DoubleClick);
    lvExplorer.SmallImageList = imgList;
    lvExplorer.LargeImageList = imgList;
}

private static ImageList GetFolderImageList()
{
    Image folderImg = Image.FromFile(@"C:\Windows\WinSxS\amd64_microsoft-windows-printing-fdprint_31bf3856ad364e35_6.3.9600.17415_none_493b0b9e590044a1\folder.ico");
    ImageList imgList = new ImageList();
    imgList.Images.Add(folderImg);
    return imgList;
}

private void lvExplorer_DoubleClick(object sender, EventArgs e)
{
    string path = lvExplorer.SelectedItems[0].Text;
    OpenDirectory(path);
}

private void OpenDirectory(string path)
{
    try 
    {
        lvExplorer.Items.Clear();
        string newPath = _controller.AddDirectoryAndGetPath(path);
        ShowDirectoriesInListView(newPath);
    }
    catch (Exception ex) 
    {
        MessageBox.Show(ex.Message);
    }
}

private void ShowDirectoriesInListView(string path)
{
    DirectoryInfo info = new DirectoryInfo(path);

    DirectoryInfo parent = info.Parent;
    if (parent != null) 
    {
        lvExplorer.Items.Add(new System.Windows.Forms.ListViewItem("...", 0));
    }

    foreach (DirectoryInfo dInfo in info.GetDirectories())
    {
        lvExplorer.Items.Add(new System.Windows.Forms.ListViewItem(dInfo.Name, 0));
    }
}
}

从这里开始,您应该了解如何使用 ListView 并添加您的文件。

子项目

如果你想要一个细节视图,你可以改变你的 InitializeListView 方法

private void InitializeListView(ImageList imgList)
{
    lvExplorer.DoubleClick += new System.EventHandler(this.lvExplorer_DoubleClick);
    lvExplorer.SmallImageList = imgList;
    lvExplorer.LargeImageList = imgList;
    CreateHeaders();
    lvExplorer.View = View.Details;
}

private void CreateHeaders()
{
    ColumnHeader header;

    header = new ColumnHeader();
    header.Text = "DirectoryName";
    lvExplorer.Columns.Add(header);

    header = new ColumnHeader();
    header.Text = "LastWriteTime";
    lvExplorer.Columns.Add(header);
}

我们在这里创建了两个标题列,并将 ListView 的 View 属性设置为 Details。

如果您现在将 subItems 添加到ShowDirectoriesInListView方法,您将获得非常好的目录详细信息视图。

private void ShowDirectoriesInListView(string path)
{
    DirectoryInfo info = new DirectoryInfo(path);

    DirectoryInfo parent = info.Parent;
    if (parent != null) 
    {
        lvExplorer.Items.Add(new System.Windows.Forms.ListViewItem("...", 0));
    }

    foreach (DirectoryInfo dInfo in info.GetDirectories())
    {
        ListViewItem item = new System.Windows.Forms.ListViewItem(dInfo.Name, 0);
        item.Tag = dInfo.Name;

        //Add some subitems here
        System.Windows.Forms.ListViewItem.ListViewSubItem subItem = new ListViewItem.ListViewSubItem();
        subItem.Text = dInfo.LastWriteTime.ToShortDateString();
        item.SubItems.Add(subItem); 
        lvExplorer.Items.Add(item);
    }
}

如果您是第一次使用 ListView,这些子项(在 ListViewItem.SubItems 集合中列出)有点令人困惑。 项目代表 ListView 的第一列,而子项目代表右侧的列。 因此,子项并不是您可能想到的子目录。

这篇文章向您展示了如何处理项目上的双击事件: https : //stackoverflow.com/a/12874269/880990

查看System.IO命名空间的DirectoryInfoFileInfo类以进行文件操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM