listview Group 收缩扩展

Posted on 2010-11-22 23:04  严武  阅读(1591)  评论(0编辑  收藏  举报

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;
    }

}

Copyright © 2024 严武
Powered by .NET 8.0 on Kubernetes