演练:使用设计器创建带有 ListView 和 TreeView 控件的资源管理器样式界面

Visual Studio 的优势之一是能够在短时间内创建具有专业外观的 Windows 窗体应用程序。 一种常见方案是使用 ListViewTreeView 控件创建用户界面 (UI),这些控件类似于 Windows 操作系统的 Windows 资源管理器功能。 Windows 资源管理器可显示用户计算机上文件和文件夹的层次结构。

创建包含 ListView 和 TreeView 控件的窗体

  1. “文件” 菜单上,指向 “新建” ,然后单击 “项目”

  2. 在“新建项目” 对话框中执行以下操作:

    1. 在类别中,选择“Visual Basic”或“Visual C#”

    2. 在模板列表中,选择“Windows 窗体应用程序”

  3. 单击“确定”。 将创建一个新的 Windows 窗体项目。

  4. 向窗体添加一个 SplitContainer 控件,然后将控件的 Dock 属性设置为 Fill

  5. 向窗体添加名为 imageList1ImageList,然后使用“属性”窗口添加两个图像:文件夹图像和文档图像,按顺序添加。

  6. 向窗体添加名为 treeview1TreeView 控件,然后将其置于 SplitContainer 控件的左侧。 在 treeView1 的“属性”窗口中,执行以下操作:

    1. Dock 属性设置为 Fill

    2. ImageList 属性设置为 imagelist1.

  7. 向窗体添加名为 listView1ListView 控件,然后将其置于 SplitContainer 控件的右侧。 在 listview1 的“属性”窗口中,执行以下操作:

    1. Dock 属性设置为 Fill

    2. View 属性设置为 Details

    3. 单击 Columns 属性中的省略号 (The Ellipsis button (...) in the Properties window of Visual Studio.) 打开 ColumnHeader 集合编辑器**。** 添加三列并将其 Text 属性分别设置为 NameTypeLast Modified。 单击 “确定” 关闭对话框。

    4. SmallImageList 属性设置为 imageList1.

  8. 实现代码以使用节点和子节点填充 TreeView。 将此代码添加到 Form1 类。

    private void PopulateTreeView()
    {
        TreeNode rootNode;
        
        DirectoryInfo info = new DirectoryInfo(@"../..");
        if (info.Exists)
        {
            rootNode = new TreeNode(info.Name);
            rootNode.Tag = info;
            GetDirectories(info.GetDirectories(), rootNode);
            treeView1.Nodes.Add(rootNode);
        }
    }
    
    private void GetDirectories(DirectoryInfo[] subDirs,
        TreeNode nodeToAddTo)
    {
        TreeNode aNode;
        DirectoryInfo[] subSubDirs;
        foreach (DirectoryInfo subDir in subDirs)
        {
            aNode = new TreeNode(subDir.Name, 0, 0);
            aNode.Tag = subDir;
            aNode.ImageKey = "folder";
            subSubDirs = subDir.GetDirectories();
            if (subSubDirs.Length != 0)
            {
                GetDirectories(subSubDirs, aNode);
            }
            nodeToAddTo.Nodes.Add(aNode);
        }
    }
    
    Private Sub PopulateTreeView() 
        Dim rootNode As TreeNode
        
        Dim info As New DirectoryInfo("../..")
        If info.Exists Then
            rootNode = New TreeNode(info.Name)
            rootNode.Tag = info
            GetDirectories(info.GetDirectories(), rootNode)
            treeView1.Nodes.Add(rootNode)
        End If
    
    End Sub
    
    Private Sub GetDirectories(ByVal subDirs() As DirectoryInfo, _
        ByVal nodeToAddTo As TreeNode)
    
        Dim aNode As TreeNode
        Dim subSubDirs() As DirectoryInfo
        Dim subDir As DirectoryInfo
        For Each subDir In subDirs
            aNode = New TreeNode(subDir.Name, 0, 0)
            aNode.Tag = subDir
            aNode.ImageKey = "folder"
            subSubDirs = subDir.GetDirectories()
            If subSubDirs.Length <> 0 Then
                GetDirectories(subSubDirs, aNode)
            End If
            nodeToAddTo.Nodes.Add(aNode)
        Next subDir
    
    End Sub
    
    
  9. 由于前面的代码使用 System.IO 命名空间,因此请在窗体顶部添加适当的 using 或 import 语句。

    using System.IO;
    
    Imports System.IO
    
  10. 在窗体的构造函数或 Load 事件处理方法中调用上一步中的设置方法。 将此代码添加到窗体构造函数。

    public Form1()
    {
        InitializeComponent();
        PopulateTreeView();
    }
    
    Public Sub New() 
        InitializeComponent()
        PopulateTreeView()
    
    End Sub
    
    
  11. 处理 treeview1NodeMouseClick 事件,并实现代码以在单击节点时使用节点的内容填充 listview1。 将此代码添加到 Form1 类。

    void treeView1_NodeMouseClick(object sender,
        TreeNodeMouseClickEventArgs e)
    {
        TreeNode newSelected = e.Node;
        listView1.Items.Clear();
        DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;
        ListViewItem.ListViewSubItem[] subItems;
        ListViewItem item = null;
    
        foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
        {
            item = new ListViewItem(dir.Name, 0);
            subItems = new ListViewItem.ListViewSubItem[]
                {new ListViewItem.ListViewSubItem(item, "Directory"),
                 new ListViewItem.ListViewSubItem(item,
                    dir.LastAccessTime.ToShortDateString())};
            item.SubItems.AddRange(subItems);
            listView1.Items.Add(item);
        }
        foreach (FileInfo file in nodeDirInfo.GetFiles())
        {
            item = new ListViewItem(file.Name, 1);
            subItems = new ListViewItem.ListViewSubItem[]
                { new ListViewItem.ListViewSubItem(item, "File"),
                 new ListViewItem.ListViewSubItem(item,
                    file.LastAccessTime.ToShortDateString())};
    
            item.SubItems.AddRange(subItems);
            listView1.Items.Add(item);
        }
    
        listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
    }
    
    Private Sub treeView1_NodeMouseClick(ByVal sender As Object, _
        ByVal e As TreeNodeMouseClickEventArgs) _
            Handles treeView1.NodeMouseClick
    
        Dim newSelected As TreeNode = e.Node
        listView1.Items.Clear()
        Dim nodeDirInfo As DirectoryInfo = _
        CType(newSelected.Tag, DirectoryInfo)
        Dim subItems() As ListViewItem.ListViewSubItem
        Dim item As ListViewItem = Nothing
    
        Dim dir As DirectoryInfo
        For Each dir In nodeDirInfo.GetDirectories()
            item = New ListViewItem(dir.Name, 0)
            subItems = New ListViewItem.ListViewSubItem() _
                {New ListViewItem.ListViewSubItem(item, "Directory"), _
                New ListViewItem.ListViewSubItem(item, _
                dir.LastAccessTime.ToShortDateString())}
    
            item.SubItems.AddRange(subItems)
            listView1.Items.Add(item)
        Next dir
        Dim file As FileInfo
        For Each file In nodeDirInfo.GetFiles()
            item = New ListViewItem(file.Name, 1)
            subItems = New ListViewItem.ListViewSubItem() _
                {New ListViewItem.ListViewSubItem(item, "File"), _
                New ListViewItem.ListViewSubItem(item, _
                file.LastAccessTime.ToShortDateString())}
    
            item.SubItems.AddRange(subItems)
            listView1.Items.Add(item)
        Next file
    
        listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize)
    
    End Sub
    
    

    如果使用的是 C#,请确保将 NodeMouseClick 事件与其事件处理方法相关联。 将此代码添加到窗体构造函数。

    this.treeView1.NodeMouseClick +=
        new TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);
    

测试应用程序

现在可以测试窗体,以确保它的行为符合预期。

测试窗体

  • 按 F5 运行该应用程序。

    你将看到一个拆分窗体,其中包含一个在左侧显示项目目录的 TreeView 控件,和一个在右侧显示三列的 ListView 控件。 可以通过选择目录节点来遍历 TreeView,然后 ListView 将填充所选目录的内容。

后续步骤

此应用程序提供了一个示例,说明可以同时使用 TreeViewListView 控件。 有关这些控件的详细信息,请参阅以下主题:

另请参阅