You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell WinForms:如何用C#扩展命名空间实现ListView组可折叠

实现WinForms ListView组可折叠的PowerShell方案

要让ListView组支持折叠,你需要通过自定义C#扩展逻辑拦截组标题的点击事件,再控制组内项的可见性。以下是完整的可运行步骤和代码:

1. 加载自定义ListView扩展类

先用Add-Type加载包含扩展逻辑的C#代码,这段代码会给ListView添加组点击事件的处理能力:

Add-Type @"
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class ListViewGroupCollapseExtension {
    private const int WM_LBUTTONDOWN = 0x0201;
    private const int LVM_SUBITEMHITTEST = 0x1039;

    [StructLayout(LayoutKind.Sequential)]
    private struct LVHITTESTINFO {
        public Point pt;
        public int flags;
        public int iItem;
        public int iSubItem;
        public int iGroup;
    }

    private ListView _listView;

    public ListViewGroupCollapseExtension(ListView listView) {
        _listView = listView;
        _listView.MouseDown += ListView_MouseDown;
    }

    private void ListView_MouseDown(object sender, MouseEventArgs e) {
        var hitTestInfo = new LVHITTESTINFO();
        hitTestInfo.pt = e.Location;
        var result = SendMessage(_listView.Handle, LVM_SUBITEMHITTEST, IntPtr.Zero, ref hitTestInfo);
        if ((hitTestInfo.flags & 0x100) != 0) {
            var group = _listView.Groups[hitTestInfo.iGroup];
            ToggleGroupCollapse(group);
        }
    }

    private void ToggleGroupCollapse(ListViewGroup group) {
        bool isCollapsed = false;
        if (group.Items.Count > 0) {
            isCollapsed = !group.Items[0].Visible;
        }

        foreach (ListViewItem item in group.Items) {
            item.Visible = isCollapsed;
        }

        group.Header = isCollapsed ? group.Header.Replace(" [-]", " [+]") : group.Header.Replace(" [+]", " [-]");
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, ref LVHITTESTINFO lp);
}
"@ -ReferencedAssemblies System.Windows.Forms, System.Drawing

2. 创建窗体并初始化ListView

在窗体代码中,实例化ListView后,创建ListViewGroupCollapseExtension对象绑定到ListView上,即可启用折叠功能:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = "可折叠ListView组演示"
$form.Size = New-Object System.Drawing.Size(600, 400)

$listView = New-Object System.Windows.Forms.ListView
$listView.Dock = [System.Windows.Forms.DockStyle]::Fill
$listView.View = [System.Windows.Forms.View]::Details
$listView.ShowGroups = $true

# 添加列
$listView.Columns.Add("名称", 200) | Out-Null
$listView.Columns.Add("类型", 150) | Out-Null
$listView.Columns.Add("大小", 100) | Out-Null

# 创建测试组和项
$group1 = New-Object System.Windows.Forms.ListViewGroup("文档 [-]", [System.Windows.Forms.HorizontalAlignment]::Left)
$group1.Items.Add((New-Object System.Windows.Forms.ListViewItem("报告.docx"))) | Out-Null
$group1.Items.Add((New-Object System.Windows.Forms.ListViewItem("表格.xlsx"))) | Out-Null

$group2 = New-Object System.Windows.Forms.ListViewGroup("图片 [-]", [System.Windows.Forms.HorizontalAlignment]::Left)
$group2.Items.Add((New-Object System.Windows.Forms.ListViewItem("风景.jpg"))) | Out-Null
$group2.Items.Add((New-Object System.Windows.Forms.ListViewItem("头像.png"))) | Out-Null

$listView.Groups.Add($group1) | Out-Null
$listView.Groups.Add($group2) | Out-Null

# 绑定折叠扩展
$collapseExtension = New-Object ListViewGroupCollapseExtension($listView)

$form.Controls.Add($listView)
$form.ShowDialog() | Out-Null

关键说明

  • 扩展类通过拦截WM_LBUTTONDOWN消息,调用LVM_SUBITEMHITTEST判断点击位置是否在组标题上
  • 点击组标题时,切换组内所有项的Visible属性,同时更新组标题文本显示折叠/展开状态([+]为折叠,[-]为展开)
  • 初始化组标题时需包含 [-],保证切换时能正确替换状态标识

内容的提问来源于stack exchange,提问作者Scepticalist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 04:20:54