1、本实例是完善了codeprofect上面charju老师“Add Group Collapse Behavior on a Listview Control”的一个限制(点击分组后面的图标不能收缩和扩展);
2、本实列适用于win2008,vista;
3、仅供参考,如有更好的方法,望大家不吝交流~
完整代码如下(只需建一个windows工程,在窗体上拖一个listview控件,取名为aoc,右击编辑代码,把下面的代码粘到窗口就可以了~,但需要注意事件对应):
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;
}
}