如何在c#中使用ListView模拟文件资源管理器?

如何在c#中使用ListView模拟文件资源管理器?,c#,windows-forms-designer,C#,Windows Forms Designer,我对C#和Windows窗体编程相当陌生。我想创建一个简单的Windows窗体,它的ListView最初填充了一些项目。然后,如果我双击一个项目,我想显示一些其他子项目。显然,顶部会有一个“…”项,将我带到父项。有人能帮我写这个简单的windows表单吗 p、 我不太熟悉C#Windows窗体应用程序体系结构(Form.Designer.cs、Form1、Program.cs等)如果您是第一次使用ListView,这些子项(列在ListViewItem.SubItems集合中)有点混乱。这些项表

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

p、 我不太熟悉C#Windows窗体应用程序体系结构(Form.Designer.cs、Form1、Program.cs等)

如果您是第一次使用ListView,这些子项(列在ListViewItem.SubItems集合中)有点混乱。这些项表示ListView的第一列,其中子项表示右侧的列。因此,正如您所想,子项不是您可能想到的子目录

这篇文章向您展示了如何处理项目上的双击事件:


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

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

你需要的是

  • 双击事件
  • 在编写Windows窗体应用程序时,应考虑将业务逻辑与视图逻辑关键字分开,这里是模型视图控制器或模型视图演示程序。p> 让我们开始吧

    我将创建一个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;
        }
    
    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名为lvExplorer,我已经将它添加到设计器中的Windows窗体中。我用Dockstyle填写了整个表格

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

        private void InitializeListView(ImageList imgList)
        {
            lvExplorer.DoubleClick += new System.EventHandler(this.lvExplorer_DoubleClick);
            lvExplorer.SmallImageList = imgList;
            lvExplorer.LargeImageList = imgList;
        }
    
    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

        private void InitializeListView(ImageList imgList)
        {
            lvExplorer.DoubleClick += new System.EventHandler(this.lvExplorer_DoubleClick);
            lvExplorer.SmallImageList = imgList;
            lvExplorer.LargeImageList = imgList;
        }
    
    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方法中设置了

    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);
    }
    
    被调用的方法应与作为参数传递到EventHandler构造函数的方法同名

    private void lvExplorer_DoubleClick(object sender, EventArgs e)
    {
        string path = lvExplorer.SelectedItems[0].Text;
        OpenDirectory(path);
    }
    
    双击某个项目时,将调用该方法,并且SelectedItems列表应填充一个项目。在此我要指出的是,selectedItems数组中可能有多个项或没有项,因此请在此方法中添加一些错误处理,或将ListView的
    MultiSelect
    属性设置为
    false
    。 所选项目的text属性由您单击的项目的目录名填充,因为我们在
    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

    如果现在将子项添加到
    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);
        }
    }
    

    太宽了。如果你刚刚开始,你真的需要遵循一个教程。你的文件浏览器怎么样了?你需要帮助吗?请随意添加一些信息,以便我可以调整我的答案