在ListView中,并非所有组都可以折叠

时间:2015-12-07 11:18:26

标签: c# winforms listview

我正在构建分组ListView。我需要扩展和折叠组。 This article on CodeProject几乎完成了这个伎俩。

问题是只有前三组正在根据需要进行扩展和折叠(就像在文章中一样)。其他人不会得到这种行为。请看截图

First 3 groups can expand and collapse, other - not

这是我从SQL数据库添加组的方法:

        foreach (DataRow dr in terminalsTable.Rows)
        {
            ListViewGroup group = new ListViewGroup();
            group.Name = dr["name"].ToString();
            lineUpView.Groups.Add(group.Name, group.Name);
        }
        SetGroupCollapse(GroupState.COLLAPSIBLE);
        foreach (DataRow vRow in dt.Rows)
        {
            item = new ListViewItem(vRow["terminal_name"].ToString());
            item.SubItems.Add(vRow["status_name"].ToString());
            item.SubItems.Add(vRow["vessel_name"].ToString());
            item.SubItems.Add(vRow["loading_window"].ToString());
            groupItems(item);
            lineUpView.Items.Add(item);
        }

SetGroupCollapse与CodeProject示例并没有什么不同:

    public class ExtListView : ListView
    {
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x202: // WM_LBUTTONUP
                    base.DefWndProc(ref m);
                    base.WndProc(ref m);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }
    }


    [StructLayout(LayoutKind.Sequential)]
    public struct LVGROUP
    {
        public int cbSize;
        public int mask;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszHeader;
        public int cchHeader;
        [MarshalAs(UnmanagedType.LPWStr)]
        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
    }

    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr window, int message, int wParam, IntPtr lParam);

    void SetGroupCollapse(GroupState groupState)
    {
        for (int i = 0; i <= lineUpView.Groups.Count; i++)
        {
            LVGROUP group = new LVGROUP();
            group.cbSize = Marshal.SizeOf(group);
            group.state = (int)groupState;
            group.mask = 4;
            group.iGroupId = i;
            IntPtr ip = IntPtr.Zero;
            try
            {
                ip = Marshal.AllocHGlobal(group.cbSize);
                Marshal.StructureToPtr(group, ip, false);
                SendMessage(lineUpView.Handle, 0x1000 + 147, i, ip); // #define LWM_SETGROUPINFO (LWM_FIRST + 147)
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (null != ip)
                    Marshal.FreeHGlobal(ip);
            }
        }
    }

请您指点一下,为什么只有前三组可以延长和折叠?

1 个答案:

答案 0 :(得分:0)

这是我最近也遇到的问题。这是由于无法保证每个组将拥有哪个ID

在我的情况下,我有10个从0-10编号的组,其中ID=1组完全丢失。我相信这是由于以前报告的Microsoft ListViews错误尚未解决。

为了解决该问题,可以使用Reflection获得ListView中每个组的实际ID(当然,将MyListView替换为您自己的{{ 1}}):

ListView

这将产生一个数组,其中每个组的 actual int[] groupIDs; FieldInfo listGroupIDMember; listGroupIDMember = typeof(ListViewGroup).GetField("id", BindingFlags.Instance | BindingFlags.NonPublic); groupIDs = new int[MyListView.Groups.Count]; for (int i = 0; i < MyListView.Groups.Count; i++) { object result = listGroupIDMember.GetValue(MyListView.Groups[i]); if (result != null && result is int) groupIDs[i] = (int)result; }

就我而言,如果我转储ID数组,可以看到我具有以下组ID:

groupIDs

0, 2, 3, 4, 5, 6, 7, 8, 9,10 函数中使用groupIDs数组代替从1到组数的计数器。在您的代码中:

SendMessage

请注意,我已将您代码中的for (int i = 0; i <= groupIDs.Length; i++) { int groupID = groupIDs[i]; ... group.iGroupId = groupID; ... SendMessage(lineUpView.Handle, 0x1000 + 147, groupID, ip); ... } 替换为i,但您显然可以按需这样做。