Example #1
0
        /// <devdoc>
        ///     Gets the real index for the given item.  lastIndex is the last return
        ///     value from GetDisplayIndex, or -1 if you don't know.  If provided,
        ///     the search for the index can be greatly improved.
        /// </devdoc>
        internal int GetDisplayIndex(ListViewItem item, int lastIndex) {

            Debug.Assert(item.listView == this, "Can't GetDisplayIndex if the list item doesn't belong to us");
            Debug.Assert(item.ID != -1, "ListViewItem has no ID yet");

            ApplyUpdateCachedItems();
            if (IsHandleCreated && !ListViewHandleDestroyed) {
                Debug.Assert(listItemsArray == null, "listItemsArray not null, even though handle created");

                NativeMethods.LVFINDINFO info = new NativeMethods.LVFINDINFO();
                info.lParam = (IntPtr) item.ID;
                info.flags = NativeMethods.LVFI_PARAM;

                int displayIndex = -1;

                if (lastIndex != -1) {
                    displayIndex = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.LVM_FINDITEM, lastIndex - 1, ref info);
                }

                if (displayIndex == -1) {
                    displayIndex = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.LVM_FINDITEM, -1 /* beginning */, ref info);
                }
                Debug.Assert(displayIndex != -1, "This item is in the list view -- why can't we find a display index for it?");
                return displayIndex;
            }
            else {
                // PERF: The only reason we should ever call this before the handle is created
                // is if the user calls ListViewItem.Index.
                Debug.Assert(listItemsArray != null, "listItemsArray is null, but the handle isn't created");

                int index = 0;
                foreach (object o in listItemsArray) {
                    if (o == item)
                        return index;
                    index++;
                }
                return -1;
            }
        }
Example #2
0
        private ListViewItem FindItem(bool isTextSearch, string text, bool isPrefixSearch, Point pt, SearchDirectionHint dir, int startIndex, bool includeSubItemsInSearch) {
            if (this.Items.Count == 0) {
                return null;
            }

            if (!IsHandleCreated)
                CreateHandle();
            if (VirtualMode) {
                SearchForVirtualItemEventArgs sviEvent = new SearchForVirtualItemEventArgs(isTextSearch, isPrefixSearch, includeSubItemsInSearch, text, pt, dir, startIndex);

                OnSearchForVirtualItem(sviEvent);
                // NOTE: this will cause a RetrieveVirtualItem event w/o a corresponding cache hint event.
                if (sviEvent.Index != -1) {
                    return this.Items[sviEvent.Index];
                } else {
                    return null;
                }
            } else {
                NativeMethods.LVFINDINFO lvFindInfo = new NativeMethods.LVFINDINFO();
                if (isTextSearch) {
                    lvFindInfo.flags = NativeMethods.LVFI_STRING;
                    lvFindInfo.flags |= (isPrefixSearch ? NativeMethods.LVFI_PARTIAL : 0);
                    lvFindInfo.psz = text;
                } else {
                    lvFindInfo.flags = NativeMethods.LVFI_NEARESTXY;
                    lvFindInfo.ptX = pt.X;
                    lvFindInfo.ptY = pt.Y;
                    // we can do this because SearchDirectionHint is set to the VK_*
                    lvFindInfo.vkDirection = (int)dir;
                }
                lvFindInfo.lParam = IntPtr.Zero;
                int index = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle),
                                                                 NativeMethods.LVM_FINDITEM,
                                                                 startIndex-1,                      // decrement startIndex so that the search is 0-based
                                                                 ref lvFindInfo);
                if (index >= 0) {
                    return Items[index];
                } else if (isTextSearch && includeSubItemsInSearch) {
                    // win32 listView control can't search inside sub items
                    for (int i = startIndex; i < this.Items.Count; i ++) {
                        ListViewItem lvi = this.Items[i];
                        for (int j = 0; j < lvi.SubItems.Count; j ++) {
                            ListViewItem.ListViewSubItem lvsi = lvi.SubItems[j];
                            // the win32 list view search for items w/ text is case insensitive
                            // do the same for sub items
                            // because we are comparing user defined strings we have to do the slower String search
                            // ie, use String.Compare(string, string, case sensitive, CultureInfo)
                            // instead of new Whidbey String.Equals overload
                            // String.Equals(string, string, StringComparison.OrdinalIgnoreCase
                            if (String.Equals(text,lvsi.Text, StringComparison.OrdinalIgnoreCase)) {
                                return lvi;
                            } else if (isPrefixSearch && CultureInfo.CurrentCulture.CompareInfo.IsPrefix(lvsi.Text, text, CompareOptions.IgnoreCase)) {
                                return lvi;
                            }
                        }
                    }
                    return null;
                } else {
                    return null;
                }
            }
        }