public TileViewControl() { this.DoubleBuffered = true; this.ResizeRedraw = true; this.SetStyle(ControlStyles.UserMouse, true); // to make control focusable this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); this.SizeChanged += (o, e) => UpdateAutoScrollSize(); this.MouseDown += (o, e) => { int idx = GetIndexAtLocation(e.Location); FocusIndex = idx; if (idx != -2 && e.Button == System.Windows.Forms.MouseButtons.Left) // no Tile at given location { SelectIndex(idx); } }; this.SelectedIndices.CollectionChanged += (o, e) => { if (e.ItemsChanged.Count == 0) return; RedrawItems(e.ItemsChanged); if (ItemSelectionChanged != null) { foreach (Delegate del in ItemSelectionChanged.GetInvocationList()) { del.DynamicInvoke(this, new ListViewItemSelectionChangedEventArgs(null, e.ItemsChanged[0], (e.Action == IndicesCollection.NotifyCollectionChangedAction.Add ? true : false))); } } }; inputTimeoutTimer.AutoReset = false; inputTimeoutTimer.Elapsed += (o, e) => { input.Clear(); Debug.Print("Text input timeout"); /*inputTimeoutTimer.Stop();*/ }; this.KeyPress += (o, e) => { // here we'll handle input // Backspace, remove last char if available if (SearchForVirtualItem != null) { if (e.KeyChar == '\b' && input.Length > 0) input.Remove(input.Length - 1, 1); else if (!char.IsControl(e.KeyChar)) input.Append(e.KeyChar); if (input.Length > 0) { SearchForVirtualItemEventArgs args = new SearchForVirtualItemEventArgs(false, true, false, input.ToString(), new Point(), SearchDirectionHint.Down, m_FocusIndex); SearchForVirtualItem(this, args); if (args.Index != m_FocusIndex && args.Index != -1) FocusIndex = args.Index; e.Handled = true; if (inputTimeoutTimer.Enabled) inputTimeoutTimer.Stop(); inputTimeoutTimer.Start(); } } Debug.Print("KeyPress: Handled:{0}, KeyChar:{1}, Key:{2}, input:\"{3}\"", e.Handled, e.KeyChar, ((Enum)(Keys)e.KeyChar).ToString(), input); }; }
private void fileList_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { viewHelper.Search(fileList, e); }
internal ListViewItem FindItemWithText (string text, bool includeSubItemsInSearch, int startIndex, bool isPrefixSearch, bool roundtrip) { if (startIndex < 0 || startIndex >= items.Count) throw new ArgumentOutOfRangeException ("startIndex"); if (text == null) throw new ArgumentNullException ("text"); if (virtual_mode) { SearchForVirtualItemEventArgs args = new SearchForVirtualItemEventArgs (true, isPrefixSearch, includeSubItemsInSearch, text, Point.Empty, SearchDirectionHint.Down, startIndex); OnSearchForVirtualItem (args); int idx = args.Index; if (idx >= 0 && idx < virtual_list_size) return items [idx]; return null; } int i = startIndex; while (true) { ListViewItem lvi = items [i]; if (isPrefixSearch) { // prefix search if (CultureInfo.CurrentCulture.CompareInfo.IsPrefix (lvi.Text, text, CompareOptions.IgnoreCase)) return lvi; } else if (String.Compare (lvi.Text, text, true) == 0) // match return lvi; if (i + 1 >= items.Count) { if (!roundtrip) break; i = 0; } else i++; if (i == startIndex) break; } // Subitems have a minor priority, so we have to do a second linear search // Also, we don't need to to a roundtrip search for them by now if (includeSubItemsInSearch) { for (i = startIndex; i < items.Count; i++) { ListViewItem lvi = items [i]; foreach (ListViewItem.ListViewSubItem sub_item in lvi.SubItems) if (isPrefixSearch) { if (CultureInfo.CurrentCulture.CompareInfo.IsPrefix (sub_item.Text, text, CompareOptions.IgnoreCase)) return lvi; } else if (String.Compare (sub_item.Text, text, true) == 0) return lvi; } } return null; }
/// <summary> /// Handle the SearchForVirtualList event, which is called when the user types into a virtual list /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void HandleSearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { // The event has e.IsPrefixSearch, but as far as I can tell, this is always false (maybe that's different under Vista) // So we ignore IsPrefixSearch and IsTextSearch and always to a case insensitve prefix match. // We can't do anything if we don't have a data source if (this.VirtualListDataSource == null) return; // Where should we start searching? If the last row is focused, the SearchForVirtualItemEvent starts searching // from the next row, which is actually an invalidate index -- so we make sure we never go past the last object. int start = Math.Min(e.StartIndex, this.VirtualListDataSource.GetObjectCount() - 1); // Give the world a chance to fiddle with or completely avoid the searching process BeforeSearchingEventArgs args = new BeforeSearchingEventArgs(e.Text, start); this.OnBeforeSearching(args); if (args.Canceled) return; // Do the search int i = this.FindMatchingRow(args.StringToFind, args.StartSearchFrom, e.Direction); // Tell the world that a search has occurred AfterSearchingEventArgs args2 = new AfterSearchingEventArgs(args.StringToFind, i); this.OnAfterSearching(args2); // If we found a match, tell the event if (i != -1) e.Index = i; }
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; } } }
private unsafe void WmReflectNotify(ref Message m) { NativeMethods.NMHDR* nmhdr = (NativeMethods.NMHDR*)m.LParam; switch (nmhdr->code) { case NativeMethods.NM_CUSTOMDRAW: CustomDraw(ref m); break; case NativeMethods.LVN_BEGINLABELEDITA: case NativeMethods.LVN_BEGINLABELEDITW: { NativeMethods.NMLVDISPINFO_NOTEXT nmlvdp = (NativeMethods.NMLVDISPINFO_NOTEXT)m.GetLParam(typeof(NativeMethods.NMLVDISPINFO_NOTEXT)); LabelEditEventArgs e = new LabelEditEventArgs(nmlvdp.item.iItem); OnBeforeLabelEdit(e); m.Result = (IntPtr)(e.CancelEdit ? 1 : 0); listViewState[LISTVIEWSTATE_inLabelEdit] = !e.CancelEdit; break; } case NativeMethods.LVN_COLUMNCLICK: { NativeMethods.NMLISTVIEW nmlv = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW)); listViewState[LISTVIEWSTATE_columnClicked] = true; columnIndex = nmlv.iSubItem; break; } case NativeMethods.LVN_ENDLABELEDITA: case NativeMethods.LVN_ENDLABELEDITW: { listViewState[LISTVIEWSTATE_inLabelEdit] = false; NativeMethods.NMLVDISPINFO nmlvdp = (NativeMethods.NMLVDISPINFO)m.GetLParam(typeof(NativeMethods.NMLVDISPINFO)); LabelEditEventArgs e = new LabelEditEventArgs(nmlvdp.item.iItem, nmlvdp.item.pszText); OnAfterLabelEdit(e); m.Result = (IntPtr)(e.CancelEdit ? 0 : 1); // from msdn: // "If the user cancels editing, the pszText member of the LVITEM structure is NULL" if (!e.CancelEdit && nmlvdp.item.pszText != null) Items[nmlvdp.item.iItem].Text = nmlvdp.item.pszText; break; } case NativeMethods.LVN_ITEMACTIVATE: OnItemActivate(EventArgs.Empty); break; case NativeMethods.LVN_BEGINDRAG: { // the items collection was modified while dragging // that means that we can't reliably give the user the item on which the dragging started // so don't tell the user about this operation... // vsWhidbey 235027 if (!this.ItemCollectionChangedInMouseDown) { NativeMethods.NMLISTVIEW nmlv = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW)); LvnBeginDrag(MouseButtons.Left, nmlv); } break; } case NativeMethods.LVN_BEGINRDRAG: { // the items collection was modified while dragging // that means that we can't reliably give the user the item on which the dragging started // so don't tell the user about this operation... // vsWhidbey 235027 if (!this.ItemCollectionChangedInMouseDown) { NativeMethods.NMLISTVIEW nmlv = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW)); LvnBeginDrag(MouseButtons.Right, nmlv); } break; } case NativeMethods.LVN_ITEMCHANGING: { NativeMethods.NMLISTVIEW* nmlv = (NativeMethods.NMLISTVIEW*)m.LParam; if ((nmlv->uChanged & NativeMethods.LVIF_STATE) != 0) { // Because the state image mask is 1-based, a value of 1 means unchecked, // anything else means checked. We convert this to the more standard 0 or 1 CheckState oldState = (CheckState)(((nmlv->uOldState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1); CheckState newState = (CheckState)(((nmlv->uNewState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1); if (oldState != newState) { ItemCheckEventArgs e = new ItemCheckEventArgs(nmlv->iItem, newState, oldState); OnItemCheck(e); m.Result = (IntPtr)(((int)e.NewValue == 0 ? 0 : 1) == (int)oldState ? 1 : 0); } } break; } case NativeMethods.LVN_ITEMCHANGED: { NativeMethods.NMLISTVIEW* nmlv = (NativeMethods.NMLISTVIEW*)m.LParam; // Check for state changes to the selected state... if ((nmlv->uChanged & NativeMethods.LVIF_STATE) != 0) { // Because the state image mask is 1-based, a value of 1 means unchecked, // anything else means checked. We convert this to the more standard 0 or 1 CheckState oldValue = (CheckState)(((nmlv->uOldState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1); CheckState newValue = (CheckState)(((nmlv->uNewState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1); if (newValue != oldValue) { ItemCheckedEventArgs e = new ItemCheckedEventArgs(Items[nmlv->iItem]); OnItemChecked(e); } int oldState = nmlv->uOldState & NativeMethods.LVIS_SELECTED; int newState = nmlv->uNewState & NativeMethods.LVIS_SELECTED; // Windows common control always fires // this event twice, once with newState, oldState, and again with // oldState, newState. // Changing this affects the behaviour as the control never // fires the event on a Deselct of an Items from multiple selections. // So leave it as it is... if (newState != oldState) { if (this.VirtualMode && nmlv->iItem == -1) { if (this.VirtualListSize > 0) { ListViewVirtualItemsSelectionRangeChangedEventArgs lvvisrce = new ListViewVirtualItemsSelectionRangeChangedEventArgs(0, this.VirtualListSize-1, newState != 0); OnVirtualItemsSelectionRangeChanged(lvvisrce); } } else { // APPCOMPAT // V1.* users implement virtualization by communicating directly to the native ListView and // by passing our virtualization implementation. // In that case, the native list view may have an item under the mouse even if our wrapper thinks the item count is 0. // And that may cause GetItemAt to throw an out of bounds exception. // See VSW 418791. if (this.Items.Count > 0) { ListViewItemSelectionChangedEventArgs lvisce = new ListViewItemSelectionChangedEventArgs(this.Items[nmlv->iItem], nmlv->iItem, newState != 0); OnItemSelectionChanged(lvisce); } } // VSWhidbey 549967 - Delay SelectedIndexChanged event because the last item isn't present yet. if (this.Items.Count == 0 || this.Items[this.Items.Count - 1] != null) { this.listViewState1[LISTVIEWSTATE1_selectedIndexChangedSkipped] = false; OnSelectedIndexChanged(EventArgs.Empty); } else { this.listViewState1[LISTVIEWSTATE1_selectedIndexChangedSkipped] = true; } } } break; } case NativeMethods.NM_CLICK: WmNmClick(ref m); // FALL THROUGH // goto case NativeMethods.NM_RCLICK; case NativeMethods.NM_RCLICK: NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO(); int displayIndex = GetIndexOfClickedItem(lvhi); MouseButtons button = nmhdr->code == NativeMethods.NM_CLICK ? MouseButtons.Left : MouseButtons.Right; Point pos = Cursor.Position; pos = PointToClientInternal(pos); if (!ValidationCancelled && displayIndex != -1) { OnClick(EventArgs.Empty); OnMouseClick(new MouseEventArgs(button, 1, pos.X, pos.Y, 0)); } if (!listViewState[LISTVIEWSTATE_mouseUpFired]) { OnMouseUp(new MouseEventArgs(button, 1, pos.X, pos.Y, 0)); listViewState[LISTVIEWSTATE_mouseUpFired] = true; } break; case NativeMethods.NM_DBLCLK: WmNmDblClick(ref m); // FALL THROUGH // goto case NativeMethods.NM_RDBLCLK; case NativeMethods.NM_RDBLCLK: NativeMethods.LVHITTESTINFO lvhip = new NativeMethods.LVHITTESTINFO(); int index = GetIndexOfClickedItem(lvhip); if (index != -1) { //just maintain state and fire double click.. in final mouseUp... listViewState[LISTVIEWSTATE_doubleclickFired] = true; } //fire Up in the Wndproc !! listViewState[LISTVIEWSTATE_mouseUpFired] = false; //problem getting the UP... outside the control... // CaptureInternal = true; break; case NativeMethods.LVN_KEYDOWN: if (CheckBoxes) { NativeMethods.NMLVKEYDOWN lvkd = (NativeMethods.NMLVKEYDOWN)m.GetLParam(typeof(NativeMethods.NMLVKEYDOWN)); if (lvkd.wVKey == (short)Keys.Space) { ListViewItem focusedItem = FocusedItem; if (focusedItem != null) { bool check = !focusedItem.Checked; if (!VirtualMode) { foreach(ListViewItem item in SelectedItems) { if (item != focusedItem) { item.Checked = check; } } } } } } break; case NativeMethods.LVN_ODCACHEHINT: // tell the user to prepare the cache: NativeMethods.NMLVCACHEHINT cacheHint = (NativeMethods.NMLVCACHEHINT) m.GetLParam(typeof(NativeMethods.NMLVCACHEHINT)); OnCacheVirtualItems(new CacheVirtualItemsEventArgs(cacheHint.iFrom, cacheHint.iTo)); break; default: if (nmhdr->code == NativeMethods.LVN_GETDISPINFO) { // we use the LVN_GETDISPINFO message only in virtual mode if (this.VirtualMode && m.LParam != IntPtr.Zero) { // we HAVE to use unsafe code because of a bug in the CLR: WHIDBEY bug 20313 NativeMethods.NMLVDISPINFO_NOTEXT dispInfo= (NativeMethods.NMLVDISPINFO_NOTEXT) m.GetLParam(typeof(NativeMethods.NMLVDISPINFO_NOTEXT)); RetrieveVirtualItemEventArgs rVI = new RetrieveVirtualItemEventArgs(dispInfo.item.iItem); OnRetrieveVirtualItem(rVI); ListViewItem lvItem = rVI.Item; if (lvItem == null) { throw new InvalidOperationException(SR.GetString(SR.ListViewVirtualItemRequired)); } lvItem.SetItemIndex(this, dispInfo.item.iItem); if ((dispInfo.item.mask & NativeMethods.LVIF_TEXT) != 0) { string text; if (dispInfo.item.iSubItem == 0) { text = lvItem.Text; // we want the item } else { if (lvItem.SubItems.Count <= dispInfo.item.iSubItem) { throw new InvalidOperationException(SR.GetString(SR.ListViewVirtualModeCantAccessSubItem)); } else { text = lvItem.SubItems[dispInfo.item.iSubItem].Text; // we want the sub item } } // use the buffer provided by the ComCtrl list view. if (dispInfo.item.cchTextMax <= text.Length) { text = text.Substring(0, dispInfo.item.cchTextMax - 1); } if (Marshal.SystemDefaultCharSize == 1) { // ANSI. Use byte byte[] buff = System.Text.Encoding.Default.GetBytes(text + "\0"); Marshal.Copy(buff, 0, dispInfo.item.pszText, text.Length + 1); } else { char[] buff = (text + "\0").ToCharArray(); Marshal.Copy(buff, 0, dispInfo.item.pszText, text.Length + 1); } } if ((dispInfo.item.mask & NativeMethods.LVIF_IMAGE) != 0 && lvItem.ImageIndex != -1) { dispInfo.item.iImage = lvItem.ImageIndex; } if ((dispInfo.item.mask & NativeMethods.LVIF_INDENT) != 0) { dispInfo.item.iIndent = lvItem.IndentCount; } /* [....]: Couldn't make this work. The dispInfo.item.iSubItem received for the subitems' text are invalid if ((dispInfo.item.mask & NativeMethods.LVIF_COLUMNS) != 0) { int cColumns = this.columnHeaders != null ? this.columnHeaders.Length : 0; dispInfo.item.cColumns = cColumns; if (cColumns > 0) { dispInfo.item.puColumns = Marshal.AllocHGlobal(cColumns * Marshal.SizeOf(typeof(int))); int[] columns = new int[cColumns]; for (int c = 0; c < cColumns; c++) { columns[c] = c + 1; } Marshal.Copy(columns, 0, dispInfo.item.puColumns, cColumns); } } */ /* [....]: VirtualMode and grouping seem to be incompatible. dispInfo.item.mask never includes NativeMethods.LVIF_GROUPID. Besides, trying to send LVM_ENABLEGROUPVIEW to the listview fails in virtual mode. if (this.GroupsEnabled && (dispInfo.item.mask & NativeMethods.LVIF_GROUPID) != 0) { dispInfo.item.iGroupId = GetNativeGroupId(lvItem); #if DEBUG Debug.Assert(SendMessage(NativeMethods.LVM_ISGROUPVIEWENABLED, 0, 0) != IntPtr.Zero, "Groups not enabled"); Debug.Assert(SendMessage(NativeMethods.LVM_HASGROUP, dispInfo.item.iGroupId, 0) != IntPtr.Zero, "Doesn't contain group id: " + dispInfo.item.iGroupId.ToString(CultureInfo.InvariantCulture)); #endif } */ if ((dispInfo.item.stateMask & NativeMethods.LVIS_STATEIMAGEMASK) != 0) { dispInfo.item.state |= lvItem.RawStateImageIndex; } Marshal.StructureToPtr(dispInfo, (IntPtr) m.LParam, false); } } else if (nmhdr->code == NativeMethods.LVN_ODSTATECHANGED) { if (VirtualMode && m.LParam != IntPtr.Zero) { NativeMethods.NMLVODSTATECHANGE odStateChange = (NativeMethods.NMLVODSTATECHANGE) m.GetLParam(typeof(NativeMethods.NMLVODSTATECHANGE)); bool selectedChanged = (odStateChange.uNewState & NativeMethods.LVIS_SELECTED) != (odStateChange.uOldState & NativeMethods.LVIS_SELECTED); if (selectedChanged) { // we have to substract 1 from iTo due to an imbecility in the win32 ListView control // see vsWhidbey 275717 - especially the ListView_CalcMinMaxIndex method. // in Vista, 275717 is fixed in windows OS side, we have don't need to work around here any more. int iTo = odStateChange.iTo; if (!UnsafeNativeMethods.IsVista) { iTo--; } ListViewVirtualItemsSelectionRangeChangedEventArgs lvvisrce = new ListViewVirtualItemsSelectionRangeChangedEventArgs(odStateChange.iFrom, iTo, (odStateChange.uNewState & NativeMethods.LVIS_SELECTED) != 0); OnVirtualItemsSelectionRangeChanged(lvvisrce); } } } else if (nmhdr->code == NativeMethods.LVN_GETINFOTIP) { if (ShowItemToolTips && m.LParam != IntPtr.Zero) { NativeMethods.NMLVGETINFOTIP infoTip = (NativeMethods.NMLVGETINFOTIP) m.GetLParam(typeof(NativeMethods.NMLVGETINFOTIP)); ListViewItem lvi = Items[infoTip.item]; if (lvi != null && !string.IsNullOrEmpty(lvi.ToolTipText)) { // MSDN: // Setting the max width has the added benefit of enabling multiline // tool tips! // UnsafeNativeMethods.SendMessage(new HandleRef(this, nmhdr->hwndFrom), NativeMethods.TTM_SETMAXTIPWIDTH, 0, SystemInformation.MaxWindowTrackSize.Width); if (Marshal.SystemDefaultCharSize == 1) { // ANSI. Use byte. // we need to copy the null terminator character ourselves byte[] byteBuf = System.Text.Encoding.Default.GetBytes(lvi.ToolTipText + "\0"); Marshal.Copy(byteBuf, 0, infoTip.lpszText, Math.Min(byteBuf.Length, infoTip.cchTextMax)); } else { // UNICODE. Use char. // we need to copy the null terminator character ourselves char[] charBuf = (lvi.ToolTipText + "\0").ToCharArray(); Marshal.Copy(charBuf, 0, infoTip.lpszText, Math.Min(charBuf.Length, infoTip.cchTextMax)); } Marshal.StructureToPtr(infoTip, (IntPtr) m.LParam, false); } } } else if (nmhdr->code == NativeMethods.LVN_ODFINDITEM) { if (VirtualMode) { NativeMethods.NMLVFINDITEM nmlvif = (NativeMethods.NMLVFINDITEM) m.GetLParam(typeof(NativeMethods.NMLVFINDITEM)); if ((nmlvif.lvfi.flags & NativeMethods.LVFI_PARAM) != 0) { m.Result = (IntPtr) (-1); return; } bool isTextSearch = ((nmlvif.lvfi.flags & NativeMethods.LVFI_STRING) != 0) || ((nmlvif.lvfi.flags & NativeMethods.LVFI_PARTIAL) != 0); bool isPrefixSearch = (nmlvif.lvfi.flags & NativeMethods.LVFI_PARTIAL) != 0; string text = String.Empty; if (isTextSearch) { text = nmlvif.lvfi.psz; } Point startingPoint = Point.Empty; if ((nmlvif.lvfi.flags & NativeMethods.LVFI_NEARESTXY) != 0) { startingPoint = new Point(nmlvif.lvfi.ptX, nmlvif.lvfi.ptY); } SearchDirectionHint dir = SearchDirectionHint.Down; if ((nmlvif.lvfi.flags & NativeMethods.LVFI_NEARESTXY) != 0) { // We can do this because SearchDirectionHint is set to the VK_* dir = (SearchDirectionHint) nmlvif.lvfi.vkDirection; } int startIndex = nmlvif.iStart; if (startIndex >= this.VirtualListSize) { // we want to search starting from the last item. Wrap around the first item. startIndex = 0; } SearchForVirtualItemEventArgs sviEvent = new SearchForVirtualItemEventArgs( isTextSearch, isPrefixSearch, false, /* includeSubItemsInSearch */ text, startingPoint, dir, nmlvif.iStart); OnSearchForVirtualItem(sviEvent); if (sviEvent.Index != -1) { m.Result = (IntPtr) sviEvent.Index; } else { m.Result = (IntPtr) (-1); } } } break; } }
/// <summary> /// Extends BeginInvoke so that when a state object is not needed, null does not need to be passed. /// <example> /// searchforvirtualitemeventhandler.BeginInvoke(sender, e, callback); /// </example> /// </summary> public static IAsyncResult BeginInvoke(this SearchForVirtualItemEventHandler searchforvirtualitemeventhandler, Object sender, SearchForVirtualItemEventArgs e, AsyncCallback callback) { if(searchforvirtualitemeventhandler == null) throw new ArgumentNullException("searchforvirtualitemeventhandler"); return searchforvirtualitemeventhandler.BeginInvoke(sender, e, callback, null); }
private void listViewAccounts_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { }
public void Search(NoFlickerListView fileList, SearchForVirtualItemEventArgs e) { bool ignoreCase = true; bool searchUp = false; int SelectedIndex = fileList.SelectedIndex; var comparisonType = ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture; if (searchUp) { for (var i = SelectedIndex - 1; i >= 0; --i) { var op = _displayedEntries[i].Name; if (op.IndexOf(e.Text, comparisonType) != -1) { e.Index = i; break; } } } else { for (int i = SelectedIndex + 1; i < fileList.Items.Count; ++i) { var op = _displayedEntries[i].Name; if (op.IndexOf(e.Text, comparisonType) != -1) { e.Index = i; break; } } } }
private void listview_onSearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { //TODO We have a search request. }
protected override void OnSearchForVirtualItem(SearchForVirtualItemEventArgs e) { e.Index = dataSource.FindIndex(e.StartIndex, c => c.Name.StartsWith(e.Text, StringComparison.OrdinalIgnoreCase)); }
private void lstTitles__SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { if (titles_ != null) { e.Index = titles_.Find(e.Text, true, false); } }
private void listViewSearchResults_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { Console.WriteLine("search"); throw new NotImplementedException(); ////We've gotten a search request. ////If e.Index is not set, the search returns null. ////Note that this only handles simple searches over the entire ////list, ignoring any other settings. Handling Direction, StartIndex, ////and the other properties of SearchForVirtualItemEventArgs is up ////to this handler. }
/// <summary>Handles the SearchForVirtualItem event of the listView control.</summary> /// <remarks>This will be used for keyboard search, which is an important UI feature.</remarks> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.Forms.SearchForVirtualItemEventArgs"/> instance containing the event data.</param> private void listView_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { // Note 1: The IsPrefix property of SearchForVirtualItemEventArgs seems to be false for keyboard prefix search events… // Since this is the only use we'll have of this method, we can assume this is always a prefix search. // Note 2: We'll assume that we are always searching forward. (This is important for "proximity" search) if (rootNode == null) return; // Since we are processing filenames, the invariant culture will be used here. var nodes = rootNode.Nodes; // Assuming the nodes re sorted alphabetically (they should be !), the binary search is the most efficient choice. int prefixLength = e.Text.Length; int low, high; // These will represent the dynamic search range. int difference; // Match the prefix against the start item. difference = string.Compare(nodes[e.StartIndex].Text, 0, e.Text, 0, prefixLength, StringComparison.OrdinalIgnoreCase); // Depending on the prefix comparison, we can either adjust search parameters or even terminate the search. ;) if (difference == 0) { // If the test is successful, then the start item was the item we were looking for ! e.Index = e.StartIndex; return; } else if (difference > 0) { // If prefix may only be found before the start item, search before low = 0; if (e.StartIndex > 0) high = e.StartIndex - 1; else return; // If start item was the first item, then the search failed. } else { // If prefix may only be found after the start item, search after if (e.StartIndex + 1 < nodes.Count) low = e.StartIndex + 1; else return; // If start item was the last item, then the search failed. high = nodes.Count - 1; } // In this algorithm, we may have low == high, but this is a normal (final) case. do { int pivot = (low + high) / 2; string text = nodes[pivot].Text; difference = string.Compare(text, 0, e.Text, 0, Math.Min(prefixLength, text.Length), StringComparison.OrdinalIgnoreCase); if (difference == 0) { // Once a match is found, adjust the search parameters accordingly high = (e.Index = pivot) - 1; if (text.Length == prefixLength) return; // If the full string was matched by the "prefix", we have our final result } else if (difference > 0) { if ((high = pivot - 1) < 0) return; } else if ((low = pivot + 1) == nodes.Count) return; } while (low <= high); }
private void lstGames_SearchForVirtualItem( object sender, SearchForVirtualItemEventArgs e ) { for( int i = e.StartIndex; i < displayedGames.Count; i++ ) { if( displayedGames[i].Name.StartsWith( e.Text, StringComparison.CurrentCultureIgnoreCase ) ) { e.Index = i; return; } } for( int i = 0; i < e.StartIndex; i++ ) { if( displayedGames[i].Name.StartsWith( e.Text, StringComparison.CurrentCultureIgnoreCase ) ) { e.Index = i; return; } } }
private void _list_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { var comparisonType = ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture; if (searchUp) { for (var i = SelectedIndex - 1; i >= 0; --i) { var op = packets[i].Code.ToString(); if (op.IndexOf(e.Text, comparisonType) != -1) { e.Index = i; break; } } } else { for (int i = SelectedIndex + 1; i < _list.Items.Count; ++i) { var op = packets[i].Code.ToString(); if (op.IndexOf(e.Text, comparisonType) != -1) { e.Index = i; break; } } } }
private bool SearchMatches(SearchForVirtualItemEventArgs e, StringComparison comparisonType, int i) { var op = packets[i].Name; if (op.IndexOf(e.Text, comparisonType) != -1) { e.Index = i; return true; } return false; }
void tileViewControl1_SearchItem(object sender, SearchForVirtualItemEventArgs e) { int res; if (int.TryParse(e.Text, out res)) { if (res<tileViewControl1.VirtualListSize) e.Index = res; } }
private void _list_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { var comparisonType = _ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture; if (_searchUp) { for (var i = SelectedIndex - 1; i >= 0; --i) if (SearchMatches(e, comparisonType, i)) break; } else { for (int i = SelectedIndex + 1; i < PacketView.Items.Count; ++i) if (SearchMatches(e, comparisonType, i)) break; } }
/// <include file='doc\ListView.uex' path='docs/doc[@for="ListView.OnSearchForVirtualItem"]/*' /> /// <devdoc> /// Fires the search for virtual item event. /// </devdoc> protected virtual void OnSearchForVirtualItem(SearchForVirtualItemEventArgs e) { SearchForVirtualItemEventHandler handler = (SearchForVirtualItemEventHandler) Events[EVENT_SEARCHFORVIRTUALITEM]; if (handler != null) handler(this, e); }
public void TestSearchForVirtualItemEventArgs() { SearchDirectionHint sdh = SearchDirectionHint.Right; bool includesubitems = true; int index = 84; bool isprefix = true; bool istext = false; int start = 34; Point startpoint = new Point(64,35); string text = "HiThere!"; SearchForVirtualItemEventArgs e = new SearchForVirtualItemEventArgs(istext, isprefix, includesubitems, text, startpoint, sdh, start); Assert.AreEqual(sdh, e.Direction, "A1"); Assert.AreEqual(includesubitems, e.IncludeSubItemsInSearch, "A2"); Assert.AreEqual(-1, e.Index, "A3"); Assert.AreEqual(isprefix, e.IsPrefixSearch, "A4"); Assert.AreEqual(istext, e.IsTextSearch, "A5"); Assert.AreEqual(start, e.StartIndex, "A6"); Assert.AreEqual(startpoint, e.StartingPoint, "A7"); Assert.AreEqual(text, e.Text, "A8"); e.Index = index; Assert.AreEqual(index, e.Index, "A9"); }
protected virtual void OnSearchForVirtualItem (SearchForVirtualItemEventArgs e) { SearchForVirtualItemEventHandler eh = (SearchForVirtualItemEventHandler) Events [SearchForVirtualItemEvent]; if (eh != null) eh (this, e); }
private unsafe void WmReflectNotify(ref Message m) { System.Windows.Forms.NativeMethods.LVHITTESTINFO lvhittestinfo2; System.Windows.Forms.NativeMethods.NMHDR* lParam = (System.Windows.Forms.NativeMethods.NMHDR*) m.LParam; switch (lParam->code) { case -176: case -106: { this.listViewState[0x4000] = false; System.Windows.Forms.NativeMethods.NMLVDISPINFO nmlvdispinfo = (System.Windows.Forms.NativeMethods.NMLVDISPINFO) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVDISPINFO)); LabelEditEventArgs e = new LabelEditEventArgs(nmlvdispinfo.item.iItem, nmlvdispinfo.item.pszText); this.OnAfterLabelEdit(e); m.Result = e.CancelEdit ? IntPtr.Zero : ((IntPtr) 1); if (!e.CancelEdit && (nmlvdispinfo.item.pszText != null)) { this.Items[nmlvdispinfo.item.iItem].Text = nmlvdispinfo.item.pszText; } return; } case -175: case -105: { System.Windows.Forms.NativeMethods.NMLVDISPINFO_NOTEXT nmlvdispinfo_notext = (System.Windows.Forms.NativeMethods.NMLVDISPINFO_NOTEXT) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVDISPINFO_NOTEXT)); LabelEditEventArgs args = new LabelEditEventArgs(nmlvdispinfo_notext.item.iItem); this.OnBeforeLabelEdit(args); m.Result = args.CancelEdit ? ((IntPtr) 1) : IntPtr.Zero; this.listViewState[0x4000] = !args.CancelEdit; return; } case -155: if (this.CheckBoxes) { System.Windows.Forms.NativeMethods.NMLVKEYDOWN nmlvkeydown = (System.Windows.Forms.NativeMethods.NMLVKEYDOWN) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVKEYDOWN)); if (nmlvkeydown.wVKey == 0x20) { ListViewItem focusedItem = this.FocusedItem; if (focusedItem != null) { bool flag = !focusedItem.Checked; if (!this.VirtualMode) { foreach (ListViewItem item2 in this.SelectedItems) { if (item2 != focusedItem) { item2.Checked = flag; } } } } } } return; case -114: this.OnItemActivate(EventArgs.Empty); return; case -113: { System.Windows.Forms.NativeMethods.NMLVCACHEHINT nmlvcachehint = (System.Windows.Forms.NativeMethods.NMLVCACHEHINT) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVCACHEHINT)); this.OnCacheVirtualItems(new CacheVirtualItemsEventArgs(nmlvcachehint.iFrom, nmlvcachehint.iTo)); return; } case -111: if (!this.ItemCollectionChangedInMouseDown) { System.Windows.Forms.NativeMethods.NMLISTVIEW nmlv = (System.Windows.Forms.NativeMethods.NMLISTVIEW) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLISTVIEW)); this.LvnBeginDrag(MouseButtons.Right, nmlv); } return; case -109: if (!this.ItemCollectionChangedInMouseDown) { System.Windows.Forms.NativeMethods.NMLISTVIEW nmlistview2 = (System.Windows.Forms.NativeMethods.NMLISTVIEW) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLISTVIEW)); this.LvnBeginDrag(MouseButtons.Left, nmlistview2); } return; case -108: { System.Windows.Forms.NativeMethods.NMLISTVIEW nmlistview = (System.Windows.Forms.NativeMethods.NMLISTVIEW) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLISTVIEW)); this.listViewState[0x20000] = true; this.columnIndex = nmlistview.iSubItem; return; } case -101: { System.Windows.Forms.NativeMethods.NMLISTVIEW* nmlistviewPtr2 = (System.Windows.Forms.NativeMethods.NMLISTVIEW*) m.LParam; if ((nmlistviewPtr2->uChanged & 8) != 0) { CheckState state3 = (((nmlistviewPtr2->uOldState & 0xf000) >> 12) == 1) ? CheckState.Unchecked : CheckState.Checked; CheckState state4 = (((nmlistviewPtr2->uNewState & 0xf000) >> 12) == 1) ? CheckState.Unchecked : CheckState.Checked; if (state4 != state3) { ItemCheckedEventArgs args4 = new ItemCheckedEventArgs(this.Items[nmlistviewPtr2->iItem]); this.OnItemChecked(args4); } int num = nmlistviewPtr2->uOldState & 2; int num2 = nmlistviewPtr2->uNewState & 2; if (num2 == num) { return; } if (this.VirtualMode && (nmlistviewPtr2->iItem == -1)) { if (this.VirtualListSize > 0) { ListViewVirtualItemsSelectionRangeChangedEventArgs args5 = new ListViewVirtualItemsSelectionRangeChangedEventArgs(0, this.VirtualListSize - 1, num2 != 0); this.OnVirtualItemsSelectionRangeChanged(args5); } } else if (this.Items.Count > 0) { ListViewItemSelectionChangedEventArgs args6 = new ListViewItemSelectionChangedEventArgs(this.Items[nmlistviewPtr2->iItem], nmlistviewPtr2->iItem, num2 != 0); this.OnItemSelectionChanged(args6); } if ((this.Items.Count == 0) || (this.Items[this.Items.Count - 1] != null)) { this.listViewState1[0x10] = false; this.OnSelectedIndexChanged(EventArgs.Empty); return; } this.listViewState1[0x10] = true; } return; } case -100: { System.Windows.Forms.NativeMethods.NMLISTVIEW* nmlistviewPtr = (System.Windows.Forms.NativeMethods.NMLISTVIEW*) m.LParam; if ((nmlistviewPtr->uChanged & 8) != 0) { CheckState currentValue = (((nmlistviewPtr->uOldState & 0xf000) >> 12) == 1) ? CheckState.Unchecked : CheckState.Checked; CheckState newCheckValue = (((nmlistviewPtr->uNewState & 0xf000) >> 12) == 1) ? CheckState.Unchecked : CheckState.Checked; if (currentValue == newCheckValue) { return; } ItemCheckEventArgs ice = new ItemCheckEventArgs(nmlistviewPtr->iItem, newCheckValue, currentValue); this.OnItemCheck(ice); m.Result = (((ice.NewValue == CheckState.Unchecked) ? CheckState.Unchecked : CheckState.Checked) == currentValue) ? ((IntPtr) 1) : IntPtr.Zero; } return; } case -12: this.CustomDraw(ref m); return; case -6: goto Label_0517; case -5: break; case -3: this.WmNmDblClick(ref m); goto Label_0517; case -2: this.WmNmClick(ref m); break; default: if (lParam->code == System.Windows.Forms.NativeMethods.LVN_GETDISPINFO) { if (this.VirtualMode && (m.LParam != IntPtr.Zero)) { System.Windows.Forms.NativeMethods.NMLVDISPINFO_NOTEXT structure = (System.Windows.Forms.NativeMethods.NMLVDISPINFO_NOTEXT) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVDISPINFO_NOTEXT)); RetrieveVirtualItemEventArgs args7 = new RetrieveVirtualItemEventArgs(structure.item.iItem); this.OnRetrieveVirtualItem(args7); ListViewItem item = args7.Item; if (item == null) { throw new InvalidOperationException(System.Windows.Forms.SR.GetString("ListViewVirtualItemRequired")); } item.SetItemIndex(this, structure.item.iItem); if ((structure.item.mask & 1) != 0) { string text; if (structure.item.iSubItem == 0) { text = item.Text; } else { if (item.SubItems.Count <= structure.item.iSubItem) { throw new InvalidOperationException(System.Windows.Forms.SR.GetString("ListViewVirtualModeCantAccessSubItem")); } text = item.SubItems[structure.item.iSubItem].Text; } if (structure.item.cchTextMax <= text.Length) { text = text.Substring(0, structure.item.cchTextMax - 1); } if (Marshal.SystemDefaultCharSize == 1) { Marshal.Copy(Encoding.Default.GetBytes(text + "\0"), 0, structure.item.pszText, text.Length + 1); } else { Marshal.Copy((text + "\0").ToCharArray(), 0, structure.item.pszText, text.Length + 1); } } if (((structure.item.mask & 2) != 0) && (item.ImageIndex != -1)) { structure.item.iImage = item.ImageIndex; } if ((structure.item.mask & 0x10) != 0) { structure.item.iIndent = item.IndentCount; } if ((structure.item.stateMask & 0xf000) != 0) { structure.item.state |= item.RawStateImageIndex; } Marshal.StructureToPtr(structure, m.LParam, false); return; } } else if (lParam->code == -115) { if (this.VirtualMode && (m.LParam != IntPtr.Zero)) { System.Windows.Forms.NativeMethods.NMLVODSTATECHANGE nmlvodstatechange = (System.Windows.Forms.NativeMethods.NMLVODSTATECHANGE) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVODSTATECHANGE)); if ((nmlvodstatechange.uNewState & 2) != (nmlvodstatechange.uOldState & 2)) { ListViewVirtualItemsSelectionRangeChangedEventArgs args8 = new ListViewVirtualItemsSelectionRangeChangedEventArgs(nmlvodstatechange.iFrom, nmlvodstatechange.iTo - 1, (nmlvodstatechange.uNewState & 2) != 0); this.OnVirtualItemsSelectionRangeChanged(args8); return; } } } else if (lParam->code == System.Windows.Forms.NativeMethods.LVN_GETINFOTIP) { if (this.ShowItemToolTips && (m.LParam != IntPtr.Zero)) { System.Windows.Forms.NativeMethods.NMLVGETINFOTIP nmlvgetinfotip = (System.Windows.Forms.NativeMethods.NMLVGETINFOTIP) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVGETINFOTIP)); ListViewItem item4 = this.Items[nmlvgetinfotip.item]; if ((item4 != null) && !string.IsNullOrEmpty(item4.ToolTipText)) { System.Windows.Forms.UnsafeNativeMethods.SendMessage(new HandleRef(this, lParam->hwndFrom), 0x418, 0, SystemInformation.MaxWindowTrackSize.Width); if (Marshal.SystemDefaultCharSize == 1) { byte[] bytes = Encoding.Default.GetBytes(item4.ToolTipText + "\0"); Marshal.Copy(bytes, 0, nmlvgetinfotip.lpszText, Math.Min(bytes.Length, nmlvgetinfotip.cchTextMax)); } else { char[] source = (item4.ToolTipText + "\0").ToCharArray(); Marshal.Copy(source, 0, nmlvgetinfotip.lpszText, Math.Min(source.Length, nmlvgetinfotip.cchTextMax)); } Marshal.StructureToPtr(nmlvgetinfotip, m.LParam, false); return; } } } else if ((lParam->code == System.Windows.Forms.NativeMethods.LVN_ODFINDITEM) && this.VirtualMode) { System.Windows.Forms.NativeMethods.NMLVFINDITEM nmlvfinditem = (System.Windows.Forms.NativeMethods.NMLVFINDITEM) m.GetLParam(typeof(System.Windows.Forms.NativeMethods.NMLVFINDITEM)); if ((nmlvfinditem.lvfi.flags & 1) != 0) { m.Result = (IntPtr) (-1); return; } bool isTextSearch = ((nmlvfinditem.lvfi.flags & 2) != 0) || ((nmlvfinditem.lvfi.flags & 8) != 0); bool isPrefixSearch = (nmlvfinditem.lvfi.flags & 8) != 0; string psz = string.Empty; if (isTextSearch) { psz = nmlvfinditem.lvfi.psz; } Point empty = Point.Empty; if ((nmlvfinditem.lvfi.flags & 0x40) != 0) { empty = new Point(nmlvfinditem.lvfi.ptX, nmlvfinditem.lvfi.ptY); } SearchDirectionHint down = SearchDirectionHint.Down; if ((nmlvfinditem.lvfi.flags & 0x40) != 0) { down = (SearchDirectionHint) nmlvfinditem.lvfi.vkDirection; } if (nmlvfinditem.iStart >= this.VirtualListSize) { } SearchForVirtualItemEventArgs args9 = new SearchForVirtualItemEventArgs(isTextSearch, isPrefixSearch, false, psz, empty, down, nmlvfinditem.iStart); this.OnSearchForVirtualItem(args9); if (args9.Index != -1) { m.Result = (IntPtr) args9.Index; return; } m.Result = (IntPtr) (-1); } return; } System.Windows.Forms.NativeMethods.LVHITTESTINFO lvhi = new System.Windows.Forms.NativeMethods.LVHITTESTINFO(); int indexOfClickedItem = this.GetIndexOfClickedItem(lvhi); MouseButtons button = (lParam->code == -2) ? MouseButtons.Left : MouseButtons.Right; Point position = Cursor.Position; position = base.PointToClientInternal(position); if (!base.ValidationCancelled && (indexOfClickedItem != -1)) { this.OnClick(EventArgs.Empty); this.OnMouseClick(new MouseEventArgs(button, 1, position.X, position.Y, 0)); } if (!this.listViewState[0x80000]) { this.OnMouseUp(new MouseEventArgs(button, 1, position.X, position.Y, 0)); this.listViewState[0x80000] = true; } return; Label_0517: lvhittestinfo2 = new System.Windows.Forms.NativeMethods.LVHITTESTINFO(); if (this.GetIndexOfClickedItem(lvhittestinfo2) != -1) { this.listViewState[0x40000] = true; } this.listViewState[0x80000] = false; base.CaptureInternal = true; }
public ListViewItem FindNearestItem (SearchDirectionHint dir, Point point) { if (dir < SearchDirectionHint.Left || dir > SearchDirectionHint.Down) throw new ArgumentOutOfRangeException ("searchDirection"); if (view != View.LargeIcon && view != View.SmallIcon) throw new InvalidOperationException (); if (virtual_mode) { SearchForVirtualItemEventArgs args = new SearchForVirtualItemEventArgs (false, false, false, String.Empty, point, dir, 0); OnSearchForVirtualItem (args); int idx = args.Index; if (idx >= 0 && idx < virtual_list_size) return items [idx]; return null; } ListViewItem item = null; int min_dist = Int32.MaxValue; // // It looks like .Net does a previous adjustment // switch (dir) { case SearchDirectionHint.Up: point.Y -= item_size.Height; break; case SearchDirectionHint.Down: point.Y += item_size.Height; break; case SearchDirectionHint.Left: point.X -= item_size.Width; break; case SearchDirectionHint.Right: point.X += item_size.Width; break; } for (int i = 0; i < items.Count; i++) { Point item_loc = GetItemLocation (i); if (dir == SearchDirectionHint.Up) { if (point.Y < item_loc.Y) continue; } else if (dir == SearchDirectionHint.Down) { if (point.Y > item_loc.Y) continue; } else if (dir == SearchDirectionHint.Left) { if (point.X < item_loc.X) continue; } else if (dir == SearchDirectionHint.Right) { if (point.X > item_loc.X) continue; } int x_dist = point.X - item_loc.X; int y_dist = point.Y - item_loc.Y; int dist = x_dist * x_dist + y_dist * y_dist; if (dist < min_dist) { item = items [i]; min_dist = dist; } } return item; }
private ListViewItem FindItem(bool isTextSearch, string text, bool isPrefixSearch, Point pt, SearchDirectionHint dir, int startIndex, bool includeSubItemsInSearch) { if (this.Items.Count != 0) { if (!base.IsHandleCreated) { this.CreateHandle(); } if (this.VirtualMode) { SearchForVirtualItemEventArgs e = new SearchForVirtualItemEventArgs(isTextSearch, isPrefixSearch, includeSubItemsInSearch, text, pt, dir, startIndex); this.OnSearchForVirtualItem(e); if (e.Index != -1) { return this.Items[e.Index]; } return null; } System.Windows.Forms.NativeMethods.LVFINDINFO lParam = new System.Windows.Forms.NativeMethods.LVFINDINFO(); if (isTextSearch) { lParam.flags = 2; lParam.flags |= isPrefixSearch ? 8 : 0; lParam.psz = text; } else { lParam.flags = 0x40; lParam.ptX = pt.X; lParam.ptY = pt.Y; lParam.vkDirection = (int) dir; } lParam.lParam = IntPtr.Zero; int num = (int) System.Windows.Forms.UnsafeNativeMethods.SendMessage(new HandleRef(this, base.Handle), System.Windows.Forms.NativeMethods.LVM_FINDITEM, startIndex - 1, ref lParam); if (num >= 0) { return this.Items[num]; } if (isTextSearch && includeSubItemsInSearch) { for (int i = startIndex; i < this.Items.Count; i++) { ListViewItem item = this.Items[i]; for (int j = 0; j < item.SubItems.Count; j++) { ListViewItem.ListViewSubItem item2 = item.SubItems[j]; if (string.Equals(text, item2.Text, StringComparison.OrdinalIgnoreCase)) { return item; } if (isPrefixSearch && CultureInfo.CurrentCulture.CompareInfo.IsPrefix(item2.Text, text, CompareOptions.IgnoreCase)) { return item; } } } } } return null; }
private void listViewSessions_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { }
protected virtual void OnSearchForVirtualItem(SearchForVirtualItemEventArgs e) { throw null; }