//----------------------------------------------------------------------------------- #region OnEvents protected virtual void OnAfterSearching(AfterSearchingEventArgs e) { if (this.AfterSearching != null) { this.AfterSearching(this, e); } }
protected virtual void HandleSearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { if (this.DataSource != null) { int startSearchFrom = Math.Min(e.StartIndex, this.DataSource.GetObjectCount() - 1); BeforeSearchingEventArgs args = new BeforeSearchingEventArgs(e.Text, startSearchFrom); this.OnBeforeSearching(args); if (!args.Canceled) { int indexSelected = this.FindMatchingRow(args.StringToFind, args.StartSearchFrom, e.Direction); AfterSearchingEventArgs args2 = new AfterSearchingEventArgs(args.StringToFind, indexSelected); this.OnAfterSearching(args2); if (indexSelected != -1) { e.Index = indexSelected; } } } }
/// <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.DataSource == 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.DataSource.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; } }
/// <summary> /// Handle the search for item m if possible. /// </summary> /// <param name="m">The m to be processed</param> /// <returns>bool to indicate if the m has been handled</returns> protected virtual bool HandleChar(ref Message m) { // Trigger a normal KeyPress event, which listeners can handle if they want. // Handling the event stops ObjectListView's fancy search-by-typing. if (this.ProcessKeyEventArgs(ref m)) return true; const int MILLISECONDS_BETWEEN_KEYPRESSES = 1000; // What character did the user type and was it part of a longer string? char character = (char)m.WParam.ToInt32(); //TODO: Will this work on 64 bit or MBCS? if (character == (char)Keys.Back) { // Backspace forces the next key to be considered the start of a new search this.timeLastCharEvent = 0; return true; } if (System.Environment.TickCount < (this.timeLastCharEvent + MILLISECONDS_BETWEEN_KEYPRESSES)) this.lastSearchString += character; else this.lastSearchString = character.ToString(); // If this control is showing checkboxes, we want to ignore single space presses, // since they are used to toggle the selected checkboxes. if (this.CheckBoxes && this.lastSearchString == " ") { this.timeLastCharEvent = 0; return true; } // Where should the search start? int start = 0; ListViewItem focused = this.FocusedItem; if (focused != null) { start = this.GetItemIndexInDisplayOrder(focused); // If the user presses a single key, we search from after the focused item, // being careful not to march past the end of the list if (this.lastSearchString.Length == 1) { start += 1; if (start == this.GetItemCount()) start = 0; } } // Give the world a chance to fiddle with or completely avoid the searching process BeforeSearchingEventArgs args = new BeforeSearchingEventArgs(this.lastSearchString, start); this.OnBeforeSearching(args); if (args.Canceled) return true; // The parameters of the search may have been changed string searchString = args.StringToFind; start = args.StartSearchFrom; // Do the actual search int found = this.FindMatchingRow(searchString, start, SearchDirectionHint.Down); if (found >= 0) { // Select and focus on the found item this.BeginUpdate(); try { this.SelectedIndices.Clear(); ListViewItem lvi = this.GetNthItemInDisplayOrder(found); lvi.Selected = true; lvi.Focused = true; this.EnsureVisible(lvi.Index); } finally { this.EndUpdate(); } } // Tell the world that a search has occurred AfterSearchingEventArgs args2 = new AfterSearchingEventArgs(searchString, found); this.OnAfterSearching(args2); if (!args2.Handled) { if (found < 0) System.Media.SystemSounds.Beep.Play(); } // When did this event occur? this.timeLastCharEvent = System.Environment.TickCount; return true; }
/// <summary> /// /// </summary> /// <param name="e"></param> protected virtual void OnAfterSearching(AfterSearchingEventArgs e) { if (this.AfterSearching != null) this.AfterSearching(this, e); }
/// <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; }