// Removes this element from the selection
        void ISelectionItemProvider.RemoveFromSelection()
        {
            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            // simple case: item is not selected
            if (!WindowsListView.IsItemSelected(_hwnd, _item))
            {
                return;
            }

            // object does not support multi-selection
            if (!WindowsListView.MultiSelected(_hwnd))
            {
                IRawElementProviderSimple container = ((ISelectionItemProvider)this).SelectionContainer;
                bool selectionRequired = container != null ? ((ISelectionProvider)container).IsSelectionRequired : true;

                // For single selection containers that IsSelectionRequired == false a
                // RemoveFromSelection is valid.
                if (selectionRequired)
                {
                    throw new InvalidOperationException(SR.Get(SRID.SelectionRequired));
                }
            }

            // try to unselect the item
            if (!WindowsListView.UnSelectItem(_hwnd, _item))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
        }
Exemple #2
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        // retrieve current ToggleState
        private ToggleState GetToggleState()
        {
            ListViewItem.CheckState current = (ListViewItem.CheckState)WindowsListView.GetCheckedState(_hwnd, _listviewItem);

            switch (current)
            {
            case ListViewItem.CheckState.NoCheckbox:
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            case ListViewItem.CheckState.Checked:
            {
                return(ToggleState.On);
            }

            case ListViewItem.CheckState.Unchecked:
            {
                return(ToggleState.Off);
            }
            }

            // developer defined custom values which cannot be interpret outside of the app's scope
            return(ToggleState.Indeterminate);
        }
        // To test if a list view item is offscreen, we need to
        // take into account the fact that it may be obscured by
        // the list view header.
        internal override bool IsOffscreen()
        {
            IntPtr hwndHeader = WindowsListView.ListViewGetHeader(_hwnd);

            if (hwndHeader != IntPtr.Zero)
            {
                NativeMethods.Win32Rect listViewRect = new NativeMethods.Win32Rect();
                NativeMethods.Win32Rect headerRect   = new NativeMethods.Win32Rect();
                if (Misc.GetWindowRect(hwndHeader, ref headerRect) &&
                    Misc.GetClientRectInScreenCoordinates(_hwnd, ref listViewRect))
                {
                    // Remove the listview header rect.
                    listViewRect.top = headerRect.bottom;

                    NativeMethods.Win32Rect itemRect =
                        new NativeMethods.Win32Rect(BoundingRectangle);
                    if (!listViewRect.IsEmpty &&
                        !Misc.IsItemVisible(ref listViewRect, ref itemRect))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        internal bool AreGroupsValid()
        {
            int count = _groups.Count;

            for (int i = 0; i < count; i++)
            {
                Group group = (Group)_groups[i];

                if (!ListViewHasGroup(_hwnd, group._groupID))
                {
                    return(false);
                }
            }

            // Make sure that no new group have been added, try to match all the GroupId to an
            // existing one.
            int itemCount = WindowsListView.GetItemCount(_hwnd);

            NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6();

            item.mask = NativeMethods.LVIF_GROUPID;

            for (item.iItem = 0; item.iItem < itemCount; item.iItem++)
            {
                if (!XSendMessage.GetItem(_hwnd, ref item) || GetGroup(item.iGroupID) == null)
                {
                    return(false);
                }
            }

            return(true);
        }
        internal GroupManager this[IntPtr hwnd]
        {
            get
            {
                if (!WindowsListView.IsGroupViewEnabled(hwnd))
                {
                    // Group was disabled but we did not get the needed event
                    // since for some things events are not being sent
                    // (e.g: Going from some LV modes to - List mode, List mode does not have Groups)

                    // Microsoft - We may want to consider raising the event here
                    // The M7 work on checking if LE is valid however is the better way of going
                    // WindowsListView.RemoveGroupAndRaiseLogicalChangedEvent(_hwnd);
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                // The group may have been discarded by the reorder winevent.
                EnsureCreation(hwnd);

                GroupManager manager = _groupManagers[hwnd] as GroupManager;
                if (manager == null)
                {
                    // E.G. Going from the List mode to the something that has Group will cause this

                    // Microsoft- We may want to consider raising the event here
                    // The M7 work on checking if LE is valid however is the better way of going
                    // WindowsListView.RaiseLogicalChangedEvent(hwnd);
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }
                return(manager);
            }
        }
        internal GroupManager this[IntPtr hwnd]
        {
            get
            {
                if (!WindowsListView.IsGroupViewEnabled(hwnd))
                {
                    // Group was disabled but we did not get the needed event
                    // since for some things events are not being sent
                    // (e.g: Going from some LV modes to - List mode, List mode does not have Groups)

                    // alexsn @


                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                // The group may have been discarded by the reorder winevent.
                EnsureCreation(hwnd);

                GroupManager manager = _groupManagers[hwnd] as GroupManager;
                if (manager == null)
                {
                    // E.G. Going from the List mode to the something that has Group will cause this

                    // alexsn @


                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }
                return(manager);
            }
        }
        //------------------------------------------------------
        //
        //  Patterns Implementation
        //
        //------------------------------------------------------

        #region ProxySimple Interface

        // Returns a pattern interface if supported.
        internal override object GetPatternProvider(AutomationPattern iid)
        {
            if (iid == InvokePattern.Pattern && WindowsListView.ListViewInvokable(_hwnd))
            {
                return(this);
            }

            if (iid == SelectionItemPattern.Pattern)
            {
                return(this);
            }

            if (iid == ValuePattern.Pattern && WindowsListView.ListViewEditable(_hwnd))
            {
                return(this);
            }

            if (iid == GridItemPattern.Pattern && IsImplementingGrid(_hwnd))
            {
                return(this);
            }

            if (iid == TogglePattern.Pattern && IsItemWithCheckbox(_hwnd, _item))
            {
                return(CreateListViewItemCheckbox());
            }

            if (iid == ScrollItemPattern.Pattern && WindowScroll.IsScrollable(_hwnd))
            {
                return(this);
            }

            return(null);
        }
        // ------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        internal ListViewSubItem(IntPtr hwnd, ProxyFragment parent, int item, int itemParent)
            : base(hwnd, parent, item)
        {
            // Is used to discriminate between items in a collection.
            _itemParent = itemParent;

            _cControlType = WindowsListView.ListViewEditable(hwnd) ? ControlType.Edit : ControlType.Text;
        }
        // retrieves listview item/subitem text
        internal static string GetText(IntPtr hwnd, int item, int subitem)
        {
            NativeMethods.LVITEM lvitem = new NativeMethods.LVITEM();

            lvitem.mask     = NativeMethods.LVIF_TEXT;
            lvitem.iItem    = item;
            lvitem.iSubItem = subitem;
            return(WindowsListView.GetItemText(hwnd, lvitem));
        }
        //------------------------------------------------------
        //
        //  Protected Methods
        //
        //------------------------------------------------------

        #region Protected Methods

        // This routine is only called on elements belonging to an hwnd that has the focus.
        protected override bool IsFocused()
        {
            if (Misc.IsComctrlV6OnOsVerV6orHigher(_hwnd))
            {
                int column = (int)Misc.ProxySendMessage(_hwnd, NativeMethods.LVM_GETFOCUSEDCOLUMN, IntPtr.Zero, IntPtr.Zero);
                return(column == _item);
            }

            return(WindowsListView.IsItemFocused(_hwnd, _itemParent));
        }
        // detect if given listviewitem has a checkbox
        internal static bool IsItemWithCheckbox(IntPtr hwnd, int item)
        {
            if (!WindowsListView.CheckBoxes(hwnd))
            {
                return(false);
            }

            // this listview supports checkbox, detect if
            // current item has it
            return(CheckState.NoCheckbox != (CheckState)WindowsListView.GetCheckedState(hwnd, item));
        }
        // detect if this listviewitem needs to support GridItem pattern
        static private bool IsImplementingGrid(IntPtr hwnd)
        {
            // in the detail mode, GridItem will be implemented on the subitem
            // and not item
            if (WindowsListView.IsDetailMode(hwnd))
            {
                return(false);
            }

            return(WindowsListView.IsListMode(hwnd) || WindowsListView.ListViewAutoArrange(hwnd));
        }
Exemple #13
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        // retrieve bounding rectangle of the listview checkbox
        internal static NativeMethods.Win32Rect ListViewCheckBoxRect(IntPtr hwnd, int item)
        {
            //  Rare special case
            if (WindowsListView.FullRowSelect(hwnd) && WindowsListView.IsDetailMode(hwnd))
            {
                // Get listview window rect
                NativeMethods.Win32Rect controlRectangle = NativeMethods.Win32Rect.Empty;

                if (!Misc.GetWindowRect(hwnd, ref controlRectangle))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                // BOUNDS == SELECTBOUNDS, hence cannot rely on them
                // will rely on the ICON or LABEL
                // Try icon first since it is the closest to the checkbox
                NativeMethods.Win32Rect rc;

                if ((WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_ICON, out rc) && rc.left != rc.right) || (WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_LABEL, out rc) && rc.left != rc.right))
                {
                    int right = controlRectangle.left + (rc.left - controlRectangle.left);

                    return(new NativeMethods.Win32Rect(controlRectangle.left, rc.top, right, rc.bottom));
                }
            }
            else
            {
                // Very common, simple case
                NativeMethods.Win32Rect wholeItem;

                if (!WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_BOUNDS, out wholeItem))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                NativeMethods.Win32Rect selectable;

                if (!WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_SELECTBOUNDS, out selectable))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                if (Misc.IsControlRTL(hwnd))
                {
                    return(new NativeMethods.Win32Rect(selectable.right, wholeItem.top, wholeItem.right, wholeItem.bottom));
                }
                else
                {
                    return(new NativeMethods.Win32Rect(wholeItem.left, wholeItem.top, selectable.left, wholeItem.bottom));
                }
            }

            return(NativeMethods.Win32Rect.Empty);
        }
        IRawElementProviderSimple [] ITableItemProvider.GetColumnHeaderItems()
        {
            IntPtr hwndHeader = WindowsListView.ListViewGetHeader(_hwnd);

            if (SafeNativeMethods.IsWindowVisible(hwndHeader))
            {
                WindowsSysHeader header = (WindowsSysHeader)WindowsSysHeader.Create(hwndHeader, 0);
                return(new IRawElementProviderSimple [] { new WindowsSysHeader.HeaderItem(hwndHeader, header, _item) });
            }
            return(null);
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal static ProxySimple ElementProviderFromPoint(IntPtr hwnd, ProxyFragment parent, int item, int x, int y)
        {
            NativeMethods.LVHITTESTINFO_INTERNAL hitTest = WindowsListView.SubitemHitTest(hwnd, item, new NativeMethods.Win32Point(x, y));

            if (hitTest.iSubItem >= 0)
            {
                return(new ListViewSubItem(hwnd, parent, hitTest.iSubItem, item));
            }

            // subitems do not exist
            return(parent);
        }
            internal NativeMethods.Win32Rect CalculateRectNoHeader()
            {
                NativeMethods.Win32Rect rcLv = NativeMethods.Win32Rect.Empty;

                if (!Misc.GetWindowRect(_hwnd, ref rcLv))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                // set top to the top coordinate of the first item
                NativeMethods.Win32Rect item;
                WindowsListView.GetItemRect(_hwnd, _items[0], NativeMethods.LVIR_BOUNDS, out item);

                NativeMethods.Win32Rect groupRc;
                groupRc.top = item.top;

                // left coordinate defined by the left coordinate of the listview
                groupRc.left = rcLv.left;

                int count = Count;

                // bottom defined by the bottom coordinate of the last item
                if (count > 1)
                {
                    // get the rect of the last item in the group
                    WindowsListView.GetItemRect(_hwnd, _items[count - 1], NativeMethods.LVIR_BOUNDS, out item);
                }

                groupRc.bottom = item.bottom;

                // right coordinate defined by lv.right
                groupRc.right = rcLv.right;

                // when vertical scrollbar is present take it into account
                if (WindowScroll.Scrollable(_hwnd, NativeMethods.SB_VERT))
                {
                    NativeMethods.Win32Rect rc = GetScrollbarRect();
                    int width = rc.right - rc.left;

                    if (Misc.IsControlRTL(_hwnd))
                    {
                        // Right to left mirroring style
                        groupRc.left += width;
                    }
                    else
                    {
                        groupRc.right -= width;
                    }
                }

                return(groupRc);
            }
        //------------------------------------------------------
        //
        //  Patterns Implementation
        //
        //------------------------------------------------------

        #region ProxySimple Interface

        // Returns a pattern interface if supported.
        internal override object GetPatternProvider(AutomationPattern iid)
        {
            if (iid == GridPattern.Pattern)
            {
                return(this);
            }
            else if (iid == ExpandCollapsePattern.Pattern && WindowsListView.IsGroupViewEnabled(_hwnd))
            {
                return(this);
            }

            return(null);
        }
        // This method returns the count of either columns or rows
        // in the Grid.
        static private int GetCountOfItemsInDimension(IntPtr hwnd, int groupID, IsNewItemInDimension comparer)
        {
            // Algorithm:
            // Get the rect of the item.
            // Compare it using provided "comparer" with the previously obtained rect of the previous item in the grid
            // if comparer returns New increase the count
            int itemsCount = 0;

            GroupManager.GroupInfo groupInfo = GetGroupInfo(hwnd, groupID);

            if (groupInfo)
            {
                int [] items = groupInfo._items;
                NativeMethods.Win32Rect rc;
                NativeMethods.Win32Rect rcNext;

                // get coordinates of the first item in the grid
                if (WindowsListView.GetItemRect(hwnd, items[0], NativeMethods.LVIR_BOUNDS, out rc))
                {
                    NewItemInDimension result = NewItemInDimension.New;

                    itemsCount++; // at least one exist
                    for (int i = 1; result != NewItemInDimension.Stop && i < groupInfo._count; i++)
                    {
                        if (!WindowsListView.GetItemRect(hwnd, items[i], NativeMethods.LVIR_BOUNDS, out rcNext))
                        {
                            // Fail to get rc, makes no sense to continue
                            System.Diagnostics.Debug.Assert(false, "GetCountOfItemsInDimension: failed to get item rect");
                            return(0);
                        }

                        result = comparer(rc, rcNext);
                        if (result == NewItemInDimension.New)
                        {
                            // found a change in the rect
                            // we either have a new column or new raw
                            itemsCount++;

                            // update the rc with the new coordinates
                            rc = rcNext;
                        }
                    }
                }

                return(itemsCount);
            }

            return(-1);
        }
        // Scroll the specified headerItem horizontally into view.
        internal void ScrollIntoView(HeaderItem headerItem)
        {
            // Check if the parent is a ListView
            IntPtr hwndParent = NativeMethodsSetLastError.GetAncestor(_hwnd, NativeMethods.GA_PARENT);

            if (hwndParent != IntPtr.Zero)
            {
                if (Misc.GetClassName(hwndParent).IndexOf("SysListView32", StringComparison.Ordinal) >= 0)
                {
                    // Determine the number of pixels or columns to scroll horizontally.
                    int pixels  = 0;
                    int columns = 0;

                    // Get first and last visible header items.
                    HeaderItem firstVisibleHeaderItem;
                    HeaderItem lastVisibleHeaderItem;
                    GetVisibleHeaderItemRange(out firstVisibleHeaderItem, out lastVisibleHeaderItem);
                    if (firstVisibleHeaderItem != null && firstVisibleHeaderItem._item > headerItem._item)
                    {
                        // Scroll backward.
                        pixels  = (int)(headerItem.BoundingRectangle.Left - firstVisibleHeaderItem.BoundingRectangle.Left);
                        columns = headerItem._item - firstVisibleHeaderItem._item;
                    }
                    else if (lastVisibleHeaderItem != null && headerItem._item > lastVisibleHeaderItem._item)
                    {
                        // Scroll forward.
                        pixels  = (int)(headerItem.BoundingRectangle.Left - lastVisibleHeaderItem.BoundingRectangle.Left);
                        columns = headerItem._item - lastVisibleHeaderItem._item;
                    }

                    int horizontalScrollAmount = 0;
                    if (WindowsListView.IsListMode(hwndParent))
                    {
                        // In list mode, LVM_SCROLL uses a column count.
                        horizontalScrollAmount = columns;
                    }
                    else if (WindowsListView.IsDetailMode(hwndParent))
                    {
                        // In details mode, LVM_SCROLL uses a pixel count.
                        horizontalScrollAmount = pixels;
                    }

                    if (horizontalScrollAmount != 0)
                    {
                        Misc.ProxySendMessage(hwndParent, NativeMethods.LVM_SCROLL, new IntPtr(horizontalScrollAmount), IntPtr.Zero);
                    }
                }
            }
        }
        // retrieve an id of the group to which this lvitem belongs
        // valid only if lv has groups enabled
        static internal int GetGroupID(IntPtr hwnd, int lvItem)
        {
            System.Diagnostics.Debug.Assert(WindowsListView.IsGroupViewEnabled(hwnd), "GetGroupID: called when lv does not have groups");

            NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6();
            item.mask  = NativeMethods.LVIF_GROUPID;
            item.iItem = lvItem;

            if (XSendMessage.GetItem(hwnd, ref item))
            {
                return(item.iGroupID);
            }

            return(-1);
        }
        private void ScrollToNextWindowEntry(int count)
        {
            var maxIndex = WindowsListView.Items.Count - 1;

            if (WindowsListView.SelectedIndex >= maxIndex)
            {
                WindowsListView.SelectedIndex = 0;
            }
            else
            {
                var newIndex = WindowsListView.SelectedIndex + count;

                WindowsListView.SelectedIndex = newIndex >= maxIndex ? maxIndex : newIndex;
            }
            WindowsListView.ScrollIntoView(WindowsListView.SelectedItem);
        }
        private void ScrollToPreviousWindowEntry(int count)
        {
            const int minIndex = 0;

            if (WindowsListView.SelectedIndex <= 0)
            {
                WindowsListView.SelectedIndex = WindowsListView.Items.Count - 1;
            }
            else
            {
                var newIndex = WindowsListView.SelectedIndex - count;

                WindowsListView.SelectedIndex = newIndex <= minIndex ? minIndex : newIndex;
            }
            WindowsListView.ScrollIntoView(WindowsListView.SelectedItem);
        }
        // Returns the next sibling element in the raw hierarchy.
        // Peripheral controls have always negative values.
        // Returns null if no next child
        internal override ProxySimple GetNextSibling(ProxySimple child)
        {
            int item = child._item;

            if (WindowsListView.IsDetailMode(_hwnd))
            {
                item++;
                int countCol = GetSubItemCount(_hwnd);
                if (item >= 0 && item < countCol)
                {
                    return(CreateListViewSubItem(item));
                }
            }

            return(null);
        }
        // ------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        internal ListViewItem(IntPtr hwnd, ProxyFragment parent, int item)
            : base(hwnd, parent, item)
        {
            // Set the strings to return properly the properties.
            if (WindowsListView.IsDetailMode(hwnd))
            {
                _cControlType = ControlType.DataItem;
            }
            else
            {
                _cControlType = ControlType.ListItem;
            }
            _fHasPersistentID             = false;
            _fIsKeyboardFocusable         = true;
            _isComctrlV6OnOsVerV6orHigher = Misc.IsComctrlV6OnOsVerV6orHigher(hwnd);
        }
        // Returns the first child element in the raw hierarchy.
        internal override ProxySimple GetFirstChild()
        {
            if (IsItemWithCheckbox(_hwnd, _item))
            {
                return(CreateListViewItemCheckbox());
            }
            else if (WindowsListView.IsDetailMode(_hwnd))
            {
                int countCol = GetSubItemCount(_hwnd);
                if (countCol > 0)
                {
                    return(CreateListViewSubItem(0));
                }
            }

            return(null);
        }
        void IScrollItemProvider.ScrollIntoView()
        {
            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            // Currently this ignores the alignToTop, as there is no easy way to set something to the bottom of a listbox
            if (!WindowsListView.Scrollable(_hwnd))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            // ensure item vertical visibility
            WindowsListView.EnsureVisible(_hwnd, _item, false);
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal static int GetSubItemCount(IntPtr hwnd)
        {
            // Subitems are only available in details mode.
            if (WindowsListView.IsDetailMode(hwnd))
            {
                IntPtr hwndHeader = WindowsListView.ListViewGetHeader(hwnd);

                if (hwndHeader == IntPtr.Zero)
                {
                    return(0);
                }

                return(WindowsListView.HeaderItemCount(hwndHeader));
            }

            return(-1);
        }
        // Returns a Proxy element corresponding to the specified screen coordinates.
        internal override ProxySimple ElementProviderFromPoint(int x, int y)
        {
            NativeMethods.Win32Point             pt      = new NativeMethods.Win32Point(x, y);
            NativeMethods.LVHITTESTINFO_INTERNAL hitTest = WindowsListView.SubitemHitTest(_hwnd, pt);

            if ((hitTest.flags & NativeMethods.LVHT_EX_GROUP_HEADER) != 0)
            {
                return(this);
            }

            if ((hitTest.flags & NativeMethods.LVHT_ONITEM) != 0 && hitTest.iItem >= 0)
            {
                // create the item
                return(new ListViewItem(_hwnd, this, hitTest.iItem));
            }

            // If we did not land on an item we may be at a subset link these only exist
            // in v6 comctrl and vista or later.
            if (_isComctrlV6OnOsVerV6orHigher)
            {
                // Allocate a local LVHITTESTINFO struct.
                NativeMethods.LVHITTESTINFO_V6 hitTestNative = new NativeMethods.LVHITTESTINFO_V6(hitTest);
                unsafe
                {
                    XSendMessage.XSendGetIndex(_hwnd, NativeMethods.LVM_HITTEST, new IntPtr(-1), new IntPtr(&hitTestNative), Marshal.SizeOf(hitTestNative.GetType()));
                }

                if ((hitTestNative.flags & NativeMethods.LVHT_EX_GROUP_SUBSETLINK) != 0)
                {
                    GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);
                    int [] items = groupInfo._items;
                    if (groupInfo._count <= 0 || groupInfo._count > items.Length)
                    {
                        return(null);
                    }

                    int index = items [groupInfo._count - 1];
                    return(CreateGroupSubsetLink(index + 1));
                }
            }

            return(this);
        }
        // retrieve number of columns in the group
        static private int GetColumnCount(IntPtr hwnd, int groupID)
        {
            if (WindowsListView.IsDetailMode(hwnd))
            {
                // check group for validity
                if (IsGroupValid(hwnd, groupID))
                {
                    // When lv in the detail mode, Group will have as many columns
                    // as there header items
                    int column = ListViewItem.GetSubItemCount(hwnd);

                    return((column <= -1) ? 0 : column);
                }

                return(-1);
            }

            return(GetCountOfItemsInDimension(hwnd, groupID, new IsNewItemInDimension(IsNewColumn)));
        }
        // Returns the previous sibling element in the raw hierarchy.
        // Peripheral controls have always negative values.
        // Returns null is no previous
        internal override ProxySimple GetPreviousSibling(ProxySimple child)
        {
            int item = child._item;

            if (IsItemWithCheckbox(_hwnd, _item) && item == 0)
            {
                return(CreateListViewItemCheckbox());
            }
            else if (WindowsListView.IsDetailMode(_hwnd))
            {
                int countCol = GetSubItemCount(_hwnd);
                if (item > 0 && item < countCol)
                {
                    return(CreateListViewSubItem(item - 1));
                }
            }

            return(null);
        }