![](/img/trans.png)
[英]Using Column ImageKey in a ListView to simulate windows explorer style sorting
[英]How to simulate a file explorer using ListView in c#?
我对 C# 和 Windows 窗体编程很陌生。 我想创建一个简单的 Windows 窗体,它有一个最初填充一些项目的 ListView。 然后,如果我双击一个项目,我想显示其他一些子项目。 显然,顶部会有一个“...”项将我带到父项。 有人可以帮我写这个简单的窗体吗?
ps 我不是很熟悉 C# Windows 窗体应用程序架构(Form.Designer.cs、Form1、Program.cs 等)
如果您想使用 ListView,您可以在双击目录时填充它。
你需要的是
在编写 Windows 窗体应用程序时,您应该考虑将业务逻辑与视图逻辑分开,这里的关键字是Model view controller或Model 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
命名空间的DirectoryInfo
和FileInfo
类以进行文件操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.