gpt4 book ai didi

C# 在 ListView 中显示文件和文件夹图标

转载 作者:行者123 更新时间:2023-11-30 13:36:10 24 4
gpt4 key购买 nike

我开发了一个像文件浏览器一样工作的应用程序。
有一个 listview 显示目录中的文件和子文件夹。

如何在 ListView 中显示文件和文件夹图标

下面的方式,将文件路径添加到 ListView 中。我想显示图标:

string[] s = Directory.GetDirectories(file);
foreach (string file in s)
{
listView1.Items.Add(file);

}

最佳答案

有几种不同的方法可以做到这一点。一种方法是创建一个 ImageList 并将其链接到您的 ListView,然后检索每个单独文件的图标,将其添加到您的 ImageList,并设置 ListViewItem 以在您的 ImageList 中的适当索引处显示图标。

另一种方法是利用由 shell 维护的系统镜像列表。这将避免需要自己维护图标的重复副本。想象一下,如果您的 ListView 中有一堆文件夹。所有这些都将具有相同的图标,但如果不特别注意,您将保存与显示使用它的项目一样多的该文件夹图标的副本。 shell 实现会为您处理所有这些重复跟踪。系统图像列表仅包含所需的图标(您明确要求的图标),然后每个图标仅包含一个副本。我认为这是一个更简洁、更优雅的设计,所以让我们来实现它。我们需要一堆 P/Invoke 代码。

internal static class NativeMethods
{
public const uint LVM_FIRST = 0x1000;
public const uint LVM_GETIMAGELIST = (LVM_FIRST + 2);
public const uint LVM_SETIMAGELIST = (LVM_FIRST + 3);

public const uint LVSIL_NORMAL = 0;
public const uint LVSIL_SMALL = 1;
public const uint LVSIL_STATE = 2;
public const uint LVSIL_GROUPHEADER = 3;

[DllImport("user32")]
public static extern IntPtr SendMessage(IntPtr hWnd,
uint msg,
uint wParam,
IntPtr lParam);

[DllImport("comctl32")]
public static extern bool ImageList_Destroy(IntPtr hImageList);

public const uint SHGFI_DISPLAYNAME = 0x200;
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0;
public const uint SHGFI_SMALLICON = 0x1;
public const uint SHGFI_SYSICONINDEX = 0x4000;

[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260 /* MAX_PATH */)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};

[DllImport("shell32")]
public static extern IntPtr SHGetFileInfo(string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbSizeFileInfo,
uint uFlags);

[DllImport("uxtheme", CharSet = CharSet.Unicode)]
public static extern int SetWindowTheme(IntPtr hWnd,
string pszSubAppName,
string pszSubIdList);
}

现在,让我们使用它。出于演示目的,我将一个 ListView 控件添加到名为 listView1 的窗体中,将其设置为以“详细信息”模式显示,并将以下代码转储到窗体的 Load 事件处理程序中:

private void Form1_Load(object sender, EventArgs e)
{
// Obtain a handle to the system image list.
NativeMethods.SHFILEINFO shfi = new NativeMethods.SHFILEINFO();
IntPtr hSysImgList = NativeMethods.SHGetFileInfo("",
0,
ref shfi,
(uint)Marshal.SizeOf(shfi),
NativeMethods.SHGFI_SYSICONINDEX
| NativeMethods.SHGFI_SMALLICON);
Debug.Assert(hSysImgList != IntPtr.Zero); // cross our fingers and hope to succeed!

// Set the ListView control to use that image list.
IntPtr hOldImgList = NativeMethods.SendMessage(listView1.Handle,
NativeMethods.LVM_SETIMAGELIST,
NativeMethods.LVSIL_SMALL,
hSysImgList);

// If the ListView control already had an image list, delete the old one.
if (hOldImgList != IntPtr.Zero)
{
NativeMethods.ImageList_Destroy(hOldImgList);
}

// Set up the ListView control's basic properties.
// Put it in "Details" mode, create a column so that "Details" mode will work,
// and set its theme so it will look like the one used by Explorer.
listView1.View = View.Details;
listView1.Columns.Add("Name", 500);
NativeMethods.SetWindowTheme(listView1.Handle, "Explorer", null);

// Get the items from the file system, and add each of them to the ListView,
// complete with their corresponding name and icon indices.
string[] s = Directory.GetFileSystemEntries(@"C:\...");
foreach (string file in s)
{
IntPtr himl = NativeMethods.SHGetFileInfo(file,
0,
ref shfi,
(uint)Marshal.SizeOf(shfi),
NativeMethods.SHGFI_DISPLAYNAME
| NativeMethods.SHGFI_SYSICONINDEX
| NativeMethods.SHGFI_SMALLICON);
Debug.Assert(himl == hSysImgList); // should be the same imagelist as the one we set
listView1.Items.Add(shfi.szDisplayName, shfi.iIcon);
}
}

请注意,作为一个简单的示例程序,这几乎没有错误检查。我加入了一些 Debug.Assert 健全性检查,只是为了更好地衡量。

此外,为了完整起见,我继续添加代码,使 ListView 看起来像 Explorer 使用的那样。这由 SetWindowTheme function 处理.

还有一些 shell 可以做的其他事情,但您将在这里错过。例如,外壳覆盖——出现在某些图标上的小徽章,比如那些已经被 checkin 源代码控制系统的图标。这留给读者作为练习。 (提示:LVSIL_STATE 标志用于为 ListView 控件设置“状态”图像列表。)当然,他们不是一天写出 Explorer 的。

关于C# 在 ListView 中显示文件和文件夹图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37791149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com