C#实现listview Group收缩扩展的方法

时间:2022-02-26 12:11:24

本文实例讲述了C#实现listview Group收缩扩展的方法。分享给大家供大家参考,具体如下:

1、本实例是完善了codeprofect上面charju老师“Add Group Collapse Behavior on a Listview Control”的一个限制(点击分组后面的图标不能收缩和扩展);

2、本实列适用于win2008,vista;

3、仅供参考,如有更好的方法,望大家不吝交流~

完整代码如下(只需建一个windows工程,在窗体上拖一个listview控件,取名为aoc,右击编辑代码,把下面的代码粘到窗口就可以了~,但需要注意事件对应):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ListViewGroup
{
  public partial class MainForm : Form
  {
    public MainForm()
    {
      InitializeComponent();
    }
    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr window, int message, int wParam, ref LVHITTESTINFO lParam);
    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr window, int message, int wParam, IntPtr lParam);
    private void btCollapse_Click(object sender, EventArgs e)
    {
      SetGroupCollapse(GroupState.COLLAPSED | GroupState.COLLAPSIBLE);
    }
    private void btExpand_Click(object sender, EventArgs e)
    {
      SetGroupCollapse(GroupState.EXPANDED | GroupState.COLLAPSIBLE);
    }
    private void SetGroupCollapse(GroupState state)
    {
      for (int i = 0; i <= aoc.Groups.Count; i++)
      {
        LVGROUP group = new LVGROUP();
        group.cbSize = Marshal.SizeOf(group);
        group.state = (int)state; // LVGS_COLLAPSIBLE
        group.mask = 4; // LVGF_STATE
        group.iGroupId = i;
        IntPtr ip = IntPtr.Zero;
        try
        {
          ip = Marshal.AllocHGlobal(group.cbSize);
          Marshal.StructureToPtr(group, ip, true);
          SendMessage(aoc.Handle, 0x1000 + 147, i, ip); // #define LVM_SETGROUPINFO (LVM_FIRST + 147)
        }
        catch (Exception ex)
        {
          System.Diagnostics.Trace.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
        }
        finally
        {
          if (null != ip) Marshal.FreeHGlobal(ip);
        }
      }
    }
    private void MainForm_Load(object sender, EventArgs e)
    {
      SetGroupCollapse(GroupState.COLLAPSIBLE);
      for (int i = 0; i < aoc.Groups.Count; i++)
      {
        aoc.Groups[i].Tag = "EXPANDED";
      }
    }
    private void aoc_MouseDown(object sender, MouseEventArgs e)
    {
      LVHITTESTINFO lvHitInfo = new LVHITTESTINFO();
      Point p = new Point(e.X, e.Y);
      lvHitInfo.pt = p;
      try
      {
        int id = SendMessage(aoc.Handle, 0x1000 + 18, -1, ref lvHitInfo);
        if (lvHitInfo.flags == 0x50000000)
        {
          if (aoc.Groups[id].Tag.ToString() =="EXPANDED")
          {
            SetGroupCollapseEx(id, GroupState.COLLAPSED | GroupState.COLLAPSIBLE);
            aoc.Groups[id].Tag = "COLLAPSED";
          }
          else if ( aoc.Groups[id].Tag.ToString() == "COLLAPSED")
          {
            SetGroupCollapseEx(id, GroupState.EXPANDED | GroupState.COLLAPSIBLE);
            aoc.Groups[id].Tag = "EXPANDED";
          }
        }
        //MessageBox.Show(string.Format("RESULT={0}   FLAGS=0x{1:X}", id, lvHitInfo.flags));
      }
      catch (Exception ex)
      {
        Trace.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
      }
      finally
      {
        ;
      }
    }
    private void SetGroupCollapseEx(int id, GroupState groupState)
    {
      int i = id;
      LVGROUP group = new LVGROUP();
      group.cbSize = Marshal.SizeOf(group);
      group.state = (int)groupState; // LVGS_COLLAPSIBLE
      group.mask = 4; // LVGF_STATE
      group.iGroupId = i;
      IntPtr ip = IntPtr.Zero;
      try
      {
        ip = Marshal.AllocHGlobal(group.cbSize);
        Marshal.StructureToPtr(group, ip, true);
        SendMessage(aoc.Handle, 0x1000 + 147, i, ip); // #define LVM_SETGROUPINFO (LVM_FIRST + 147)
      }
      catch (Exception ex)
      {
        System.Diagnostics.Trace.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
      }
      finally
      {
        if (null != ip) Marshal.FreeHGlobal(ip);
      }
    }
  }
  [StructLayout(LayoutKind.Sequential)]
  public struct LVGROUP
  {
    public int cbSize;
    public int mask;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string pszHeader;
    public int cchHeader;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string pszFooter;
    public int cchFooter;
    public int iGroupId;
    public int stateMask;
    public int state;
    public int uAlign;
  }
  public enum GroupState
  {
    COLLAPSIBLE = 8,
    COLLAPSED = 1,
    EXPANDED = 0
  }
  [StructLayout(LayoutKind.Sequential)]
  public struct LVHITTESTINFO
  {
    public Point pt;
    public int flags;
    public int iItem;
    public int iSubItem;
    public int iGroup;
  }
}

希望本文所述对大家C#程序设计有所帮助。