예제 #1
0
        private void ExpandOrCollapse(bool collapse)
        {
            CheckControlEnabled();

            // Check if item can be expanded or collapsed.
            bool isCollapsed = IsCollapsed();

            if ((!collapse && !isCollapsed) || (collapse && isCollapsed))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            NativeMethods.LVGROUP group = new NativeMethods.LVGROUP();
            group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP)));
            // Note:  If we set group.mask to LVGF_GROUPID | LVGF_STATE,
            // SetGroupInfo() will fail.  Setting LVGF_STATE alone works, however.
            group.mask      = NativeMethods.LVGF_STATE;
            group.iGroupID  = _groupID;
            group.stateMask = NativeMethods.LVGS_COLLAPSED;
            group.state     = collapse ? NativeMethods.LVGS_COLLAPSED : 0;
            if (!XSendMessage.SetGroupInfo(_hwnd, group))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
        }
예제 #2
0
 protected override void OnHandleCreated(EventArgs e)
 {
     base.OnHandleCreated(e);
     if (CollapsibleGroups && Groups.Count > 0)
     {
         for (int i = 0; i < Groups.Count; i++)
         {
             NativeMethods.LVGROUP group = new NativeMethods.LVGROUP {
                 cbSize = Marshal.SizeOf(typeof(NativeMethods.LVGROUP)),
                 mask   = NativeMethods.LVGF_GROUPID
             };
             IntPtr Result = NativeMethods.SendMessage(Handle, NativeMethods.LVM_GETGROUPINFOBYINDEX, i, ref group);
             if (NativeMethods.NativeToBool(Result.ToInt32()))
             {
                 int groupId = group.iGroupId;
                 group = new NativeMethods.LVGROUP {
                     cbSize   = Marshal.SizeOf(group),
                     state    = NativeMethods.LVGS_COLLAPSIBLE,
                     mask     = NativeMethods.LVGF_STATE,
                     iGroupId = groupId
                 };
                 NativeMethods.SendMessage(Handle, NativeMethods.LVM_SETGROUPINFO, group.iGroupId, ref group);
             }
         }
     }
 }
예제 #3
0
        public void SetGroupState(ListViewGroupState state)
        {
            if (!EnvUtils.RunningOnWindows() || Environment.OSVersion.Version.Major < 6)
            {
                // Only Vista and forward
                // allows collapse of ListViewGroups
                return;
            }

            foreach (ListViewGroup lvg in Groups)
            {
                SetGrpState(lvg);
            }

            Refresh();
            return;

            void SetGrpState(ListViewGroup lstvwgrp)
            {
                int groupId    = GetGroupId(lstvwgrp);
                int groupIndex = Groups.IndexOf(lstvwgrp);

                var group = new NativeMethods.LVGROUP();

                group.CbSize = Marshal.SizeOf(group);
                group.State  = state;
                group.Mask   = NativeMethods.ListViewGroupMask.State;

                var handleRef = new HandleRef(this, Handle);

                group.IGroupId = groupId > 0 ? groupId : groupIndex;
                NativeMethods.SendMessage(handleRef, NativeMethods.LVM_SETGROUPINFO, (IntPtr)group.IGroupId, ref group);
            }
        }
 internal void UpdateGroupNative(ListViewGroupEx group, bool invalidate = true)
 {
     using (NativeMethods.LVGROUP nGroup = new NativeMethods.LVGROUP(group))
     {
         nGroup.SetState(NativeMethods.ListViewGroupState.Collapsible, collapsible);
         SendMessage(NativeMethods.ListViewMessage.SetGroupInfo, group.ID, nGroup);
     }
     if (invalidate)
     {
         base.Invalidate();
     }
 }
 public static void SetFooter(this ListViewGroup group, string footer = null, HorizontalAlignment footerAlignment = HorizontalAlignment.Left)
 {
     int groupId = GetGroupId(group);
     if (groupId >= 0)
     {
         using (NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.None))
         {
             lvgroup.Footer = footer;
             lvgroup.SetAlignment(group.HeaderAlignment, footerAlignment);
             NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
         }
     }
 }
예제 #6
0
        public static void SetTask(this ListViewGroup group, string task)
        {
            int groupId = GetGroupId(group);

            if (groupId >= 0)
            {
                using (NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.None))
                {
                    lvgroup.Task = task;
                    NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
                }
            }
        }
 internal int GetGroupId(ListViewGroup group)
 {
     NativeMethods.LVGROUP mgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.GroupId);
     try
     {
         if (0 != SendMessage(NativeMethods.ListViewMessage.GetGroupInfoByIndex, base.Groups.IndexOf(group), mgroup))
         {
             return(mgroup.ID);
         }
     }
     catch { }
     return(-1);
 }
예제 #8
0
        private static void SetState(ListViewGroup group, NativeMethods.ListViewGroupState state, bool value)
        {
            int groupId = GetGroupId(group);

            if (groupId >= 0)
            {
                NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.State);
                {
                    lvgroup.SetState(state, value);
                    NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
                }
            }
        }
예제 #9
0
        public static void SetFooter(this ListViewGroup group, string footer = null, HorizontalAlignment footerAlignment = HorizontalAlignment.Left)
        {
            int groupId = GetGroupId(group);

            if (groupId >= 0)
            {
                using (NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.None))
                {
                    lvgroup.Footer = footer;
                    lvgroup.SetAlignment(group.HeaderAlignment, footerAlignment);
                    NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
                }
            }
        }
예제 #10
0
        internal static bool IsCollapsed(IntPtr hwnd, int groupID)
        {
            bool isCollapsed = false;

            NativeMethods.LVGROUP group = new NativeMethods.LVGROUP();
            group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP)));
            group.iGroupID  = groupID;
            group.mask      = NativeMethods.LVGF_STATE;
            group.stateMask = NativeMethods.LVGS_COLLAPSED;
            // Note: return code of GetGroupInfo() is not reliable.
            XSendMessage.GetGroupInfo(hwnd, ref group); // ignore return code.
            isCollapsed = (group.state & NativeMethods.LVGS_COLLAPSED) != 0;
            return(isCollapsed);
        }
 public static void SetImage(this ListViewGroup group, int titleImageIndex, string descriptionTop = null, string descriptionBottom = null)
 {
     int groupId = GetGroupId(group);
     if (groupId >= 0)
     {
         using (NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.None))
         {
             lvgroup.TitleImageIndex = titleImageIndex;
             if (descriptionBottom != null)
                 lvgroup.DescriptionBottom = descriptionBottom;
             if (descriptionTop != null)
                 lvgroup.DescriptionTop = descriptionTop;
             NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
         }
     }
 }
예제 #12
0
        private void setGrpState(ListViewGroup lstvwgrp, ListViewGroupState state)
        {
            if (lstvwgrp == null)
                return;

            int? GrpId = GetGroupID(lstvwgrp);
            int gIndex = Groups.IndexOf(lstvwgrp);
            var group = new NativeMethods.LVGROUP();
            group.CbSize = Marshal.SizeOf(group);
            group.State = state;
            group.Mask = NativeMethods.ListViewGroupMask.State;
            var handleRef = new HandleRef(this, Handle);
            group.IGroupId = GrpId ?? gIndex;
            NativeMethods.SendMessage(handleRef,
                NativeMethods.LVM_SETGROUPINFO, (IntPtr)group.IGroupId, ref group);
            NativeMethods.SendMessage(handleRef,
                NativeMethods.LVM_SETGROUPINFO, (IntPtr)group.IGroupId, ref group);
            Refresh();
        }
예제 #13
0
        public static void SetImage(this ListViewGroup group, int titleImageIndex, string descriptionTop = null, string descriptionBottom = null)
        {
            int groupId = GetGroupId(group);

            if (groupId >= 0)
            {
                using (NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.None))
                {
                    lvgroup.TitleImageIndex = titleImageIndex;
                    if (descriptionBottom != null)
                    {
                        lvgroup.DescriptionBottom = descriptionBottom;
                    }
                    if (descriptionTop != null)
                    {
                        lvgroup.DescriptionTop = descriptionTop;
                    }
                    NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
                }
            }
        }
        private void SetAllGroupState(NativeMethods.ListViewGroupState state, bool on = true)
        {
            NativeMethods.LVGROUP group = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.State);
            group.SetState(state, on);
            //group.Subtitle = "Dog";

            foreach (ListViewGroup g in this.BaseGroups)
            {
                SendMessage(NativeMethods.ListViewMessage.SetGroupInfo, GetGroupId(g), group);
            }

            using (NativeMethods.LVGROUP grp = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.Subtitle))
            {
                int res = SendMessage(NativeMethods.ListViewMessage.GetGroupInfoByIndex, 0, grp);
                if (res >= 0)
                {
                    System.Diagnostics.Debug.WriteLine(grp.Subtitle);
                }
            }

            RecreateHandle();
        }
예제 #15
0
파일: ListView.cs 프로젝트: JianwenSun/cc
        internal void UpdateGroupNative(ListViewGroup group) {
            Debug.Assert(IsHandleCreated,"UpdateGroupNative precondition: list-view handle must be created");
            Debug.Assert(ComctlSupportsVisualStyles, "we should have checked this already");

            NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP();
            try {
                lvgroup = GetLVGROUP(group);
                int retval = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle),
                                                                  NativeMethods.LVM_SETGROUPINFO,
                                                                  group.ID,
                                                                  lvgroup);
                Debug.Assert(retval != -1, "Failed to set group info");
            }
            finally
            {
                DestroyLVGROUP(lvgroup);
            }

            // The comctl32 ListView does not correctly invalidate itself, so we need to invalidate the entire ListView
            //
            Invalidate();
        }
 public static void SetTask(this ListViewGroup group, string task)
 {
     int groupId = GetGroupId(group);
     if (groupId >= 0)
     {
         using (NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.None))
         {
             lvgroup.Task = task;
             NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
         }
     }
 }
 private int SendMessage(NativeMethods.ListViewMessage msg, int wParam, NativeMethods.LVGROUP group)
 {
     return(NativeMethods.SendMessage(this.Handle, msg, wParam, group).ToInt32());
 }
예제 #18
0
 private int SendMessage(NativeMethods.ListViewMessage msg, int wParam, NativeMethods.LVGROUP group) => NativeMethods.SendMessage(Handle, msg, wParam, group).ToInt32();
예제 #19
0
        protected override void WndProc(ref Message m)
        {
            var message      = m;
            var groupHitInfo = new Lazy <ListViewGroupHitInfo>(() => GetGroupHitInfo(message));

            switch (m.Msg)
            {
            case NativeMethods.WM_LBUTTONUP when groupHitInfo.Value?.IsCollapseButton == true:
                DefWndProc(ref m);     // collapse / expand by clicking button in group header
                break;

            case NativeMethods.LVM_INSERTGROUP:
                base.WndProc(ref m);
                HandleAddedGroup(m);
                break;

            case NativeMethods.WM_PAINT:
                _isInWmPaintMsg = true;
                base.WndProc(ref m);
                _isInWmPaintMsg = false;
                break;

            case NativeMethods.WM_REFLECT_NOTIFY when IsCustomDraw(m) && !_isInWmPaintMsg:
            case NativeMethods.WM_RBUTTONUP when IsGroupMouseEventHandled(groupHitInfo.Value, MouseButtons.Right, isDown: false) :
            case NativeMethods.WM_RBUTTONDOWN when IsGroupMouseEventHandled(groupHitInfo.Value, MouseButtons.Right, isDown: true) :
            case NativeMethods.WM_LBUTTONUP when IsGroupMouseEventHandled(groupHitInfo.Value, MouseButtons.Left, isDown: false) :
            case NativeMethods.WM_LBUTTONDOWN when IsGroupMouseEventHandled(groupHitInfo.Value, MouseButtons.Left, isDown: true) :
                break;

            default:
                base.WndProc(ref m);
                break;
            }

            void HandleAddedGroup(Message msg)
            {
                if (!IsGroupStateSupported || !AllowCollapseGroups)
                {
                    return;
                }

                int groupIndex = GetGroupIndex();

                if (groupIndex < _minGroupInsertionIndex)
                {
                    return;
                }

                var listViewGroup = Groups[groupIndex];

                SetGrpState(listViewGroup, ListViewGroupState.Collapsible);
                Invalidate();

                int GetGroupIndex()
                {
                    // https://docs.microsoft.com/en-us/windows/desktop/controls/lvm-insertgroup
                    int index = msg.WParam.ToInt32();

                    if (index == -1)
                    {
                        // -1 because addition already happened
                        return(Groups.Count - 1);
                    }

                    return(index - 1 + _minGroupInsertionIndex);
                }

                void SetGrpState(ListViewGroup grp, ListViewGroupState state)
                {
                    int groupId = GetGroupId(grp);

                    if (groupId < 0)
                    {
                        groupId = Groups.IndexOf(grp) - _minGroupInsertionIndex;
                    }

                    var lvgroup = new NativeMethods.LVGROUP();

                    lvgroup.CbSize   = Marshal.SizeOf(lvgroup);
                    lvgroup.State    = state;
                    lvgroup.Mask     = NativeMethods.ListViewGroupMask.State;
                    lvgroup.IGroupId = groupId;

                    var handleRef = new HandleRef(this, Handle);

                    NativeMethods.SendMessage(handleRef, NativeMethods.LVM_SETGROUPINFO, (IntPtr)groupId, ref lvgroup);
                }
            }

            bool IsGroupMouseEventHandled(ListViewGroupHitInfo hitInfo, MouseButtons button, bool isDown)
            {
                if (hitInfo == null)
                {
                    return(false);
                }

                var eventArgs = new ListViewGroupMouseEventArgs(button, hitInfo, 1, 0);

                if (isDown)
                {
                    GroupMouseDown?.Invoke(this, eventArgs);
                }
                else
                {
                    GroupMouseUp?.Invoke(this, eventArgs);
                }

                return(eventArgs.Handled);
            }

            bool IsCustomDraw(Message msg)
            {
                var nmhdr = (NativeMethods.NMHDR)msg.GetLParam(typeof(NativeMethods.NMHDR));

                return(nmhdr.code == NativeMethods.NM_CUSTOMDRAW);
            }
        }
예제 #20
0
파일: ListView.cs 프로젝트: JianwenSun/cc
        private NativeMethods.LVGROUP GetLVGROUP(ListViewGroup group)
        {
            NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP();
            lvgroup.mask = NativeMethods.LVGF_HEADER | NativeMethods.LVGF_GROUPID | NativeMethods.LVGF_ALIGN;

            // Header
            //
            String header = group.Header;
            lvgroup.pszHeader = Marshal.StringToHGlobalAuto(header);
            lvgroup.cchHeader = header.Length;

            // Group ID
            //
            lvgroup.iGroupId = group.ID;

            // Alignment
            //
            switch(group.HeaderAlignment) {
                case HorizontalAlignment.Left:
                    lvgroup.uAlign = NativeMethods.LVGA_HEADER_LEFT;
                    break;
                case HorizontalAlignment.Right:
                    lvgroup.uAlign = NativeMethods.LVGA_HEADER_RIGHT;
                    break;
                case HorizontalAlignment.Center:
                    lvgroup.uAlign = NativeMethods.LVGA_HEADER_CENTER;
                    break;
            }
            return lvgroup;
        }
예제 #21
0
파일: ListView.cs 프로젝트: JianwenSun/cc
        // does the Win32 part of the job of inserting the group
        private void InsertGroupNative(int index, ListViewGroup group) {
            Debug.Assert(IsHandleCreated,"InsertGroupNative precondition: list-view handle must be created");
            Debug.Assert(group == DefaultGroup || this.Groups.Contains(group),"Make sure ListView.Groups contains this group before adding the native LVGROUP. Otherwise, custom-drawing may break.");

            NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP();
            try
            {
                 lvgroup = GetLVGROUP(group);
                 int retval = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this,this.Handle),NativeMethods.LVM_INSERTGROUP,index,lvgroup);
                 Debug.Assert(retval != -1,"Failed to insert group");
            }
            finally
            {
                 DestroyLVGROUP(lvgroup);
            }
        }
 internal void SetGroupState(ListViewGroupEx group, NativeMethods.ListViewGroupState item, bool value)
 {
     NativeMethods.LVGROUP mgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.State);
     mgroup.SetState(item, value);
     SendMessage(NativeMethods.ListViewMessage.SetGroupInfo, GetGroupId(group), mgroup);
 }
예제 #23
0
        protected override void WndProc(ref Message m)
        {
            var message = m;

            switch (m.Msg)
            {
            case NativeMethods.WM_LBUTTONUP when GetGroupHitInfo(message.LParam.ToPoint())?.IsCollapseButton == true:
                DefWndProc(ref m);     // collapse / expand by clicking button in group header

                break;

            case NativeMethods.LVM_INSERTGROUP:
                base.WndProc(ref m);
                HandleAddedGroup(m);
                break;

            case NativeMethods.WM_RBUTTONUP when IsGroupMouseEventHandled(MouseButtons.Right, isDown: false) :
            case NativeMethods.WM_RBUTTONDOWN when IsGroupMouseEventHandled(MouseButtons.Right, isDown: true) :
            case NativeMethods.WM_LBUTTONUP when IsGroupMouseEventHandled(MouseButtons.Left, isDown: false) :
            case NativeMethods.WM_LBUTTONDOWN when IsGroupMouseEventHandled(MouseButtons.Left, isDown: true) :
                break;

            default:
                HandleScroll(m);
                base.WndProc(ref m);
                break;
            }

            void HandleScroll(Message msg)
            {
                ScrollEventType type;
                int?            newValue = null;

                switch (msg.Msg)
                {
                case NativeMethods.WM_VSCROLL:
                    type     = (ScrollEventType)LowWord(msg.WParam.ToInt64());
                    newValue = HighWord(msg.WParam.ToInt64());
                    break;

                case NativeMethods.WM_MOUSEWHEEL:
                    type = HighWord(msg.WParam.ToInt64()) > 0
                            ? ScrollEventType.SmallDecrement
                            : ScrollEventType.SmallIncrement;
                    break;

                case NativeMethods.WM_KEYDOWN:
                    switch ((Keys)msg.WParam.ToInt32())
                    {
                    case Keys.Up:
                        type = ScrollEventType.SmallDecrement;
                        break;

                    case Keys.Down:
                        type = ScrollEventType.SmallIncrement;
                        break;

                    case Keys.PageUp:
                        type = ScrollEventType.LargeDecrement;
                        break;

                    case Keys.PageDown:
                        type = ScrollEventType.LargeIncrement;
                        break;

                    case Keys.Home:
                        type = ScrollEventType.First;
                        break;

                    case Keys.End:
                        type = ScrollEventType.Last;
                        break;

                    default:
                        return;
                    }

                    break;

                default:
                    return;
                }

                newValue = newValue ?? NativeMethods.GetScrollPos(Handle, NativeMethods.SB_VERT);
                Scroll?.Invoke(this, new ScrollEventArgs(type, newValue.Value));

                short LowWord(long number) =>
                unchecked ((short)(number & 0x0000ffff));

                short HighWord(long number) =>
                unchecked ((short)(number >> 16));
            }

            void HandleAddedGroup(Message msg)
            {
                if (!IsGroupStateSupported || !AllowCollapseGroups)
                {
                    return;
                }

                int groupIndex = GetGroupIndex();

                if (groupIndex < _minGroupInsertionIndex)
                {
                    return;
                }

                var listViewGroup = Groups[groupIndex];

                SetGrpState(listViewGroup, ListViewGroupState.Collapsible);
                Invalidate();

                int GetGroupIndex()
                {
                    // https://docs.microsoft.com/en-us/windows/desktop/controls/lvm-insertgroup
                    int index = msg.WParam.ToInt32();

                    if (index == -1)
                    {
                        // -1 because addition already happened
                        return(Groups.Count - 1);
                    }

                    return(index - 1 + _minGroupInsertionIndex);
                }

                void SetGrpState(ListViewGroup grp, ListViewGroupState state)
                {
                    int groupId = GetGroupId(grp);

                    if (groupId < 0)
                    {
                        groupId = Groups.IndexOf(grp) - _minGroupInsertionIndex;
                    }

                    var lvgroup = new NativeMethods.LVGROUP();

                    lvgroup.CbSize   = Marshal.SizeOf(lvgroup);
                    lvgroup.State    = state;
                    lvgroup.Mask     = NativeMethods.ListViewGroupMask.State;
                    lvgroup.IGroupId = groupId;

                    var handleRef = new HandleRef(this, Handle);

                    NativeMethods.SendMessage(handleRef, NativeMethods.LVM_SETGROUPINFO, (IntPtr)groupId, ref lvgroup);
                }
            }

            bool IsGroupMouseEventHandled(MouseButtons button, bool isDown)
            {
                var hitInfo = GetGroupHitInfo(message.LParam.ToPoint());

                if (hitInfo == null)
                {
                    return(false);
                }

                var eventArgs = new ListViewGroupMouseEventArgs(button, hitInfo, 1, 0);

                if (isDown)
                {
                    GroupMouseDown?.Invoke(this, eventArgs);
                }
                else
                {
                    GroupMouseUp?.Invoke(this, eventArgs);
                }

                return(eventArgs.Handled);
            }
        }
 private static void SetState(ListViewGroup group, NativeMethods.ListViewGroupState state, bool value)
 {
     int groupId = GetGroupId(group);
     if (groupId >= 0)
     {
         NativeMethods.LVGROUP lvgroup = new NativeMethods.LVGROUP(NativeMethods.ListViewGroupMask.State);
         {
             lvgroup.SetState(state, value);
             NativeMethods.SendMessage(group.ListView.Handle, (uint)NativeMethods.ListViewMessage.SetGroupInfo, (IntPtr)groupId, lvgroup);
         }
     }
 }