/// <summary> /// Places the control in search mode. /// </summary> private void EnterSearchMode() { _inSearchMode = true; BeginUpdate(); _normalSelectedNode = SelectedNode; // copy normal nodes _normalNodes.Clear(); _normalNodes.AddRange(Nodes); // clear and make way for search results Nodes.Clear(); SelectedNode = null; EndUpdate(); DropDownControl.ProcessKeys = false; Cursor = Cursors.IBeam; }
void _services_TextChanged(object sender, EventArgs e) { // cancel any existing search operation if (_cts != null) { _cts.Cancel(); _cts.Dispose(); _cts = null; } if (_services.Length > 0) { if (!_inSearchMode) { EnterSearchMode(); } if (_services.Length >= MinSearchTermLength) { // start async search operation BeginUpdate(); Nodes.Clear(); Nodes.Add(new ComboTreeNode("Searching...") { Selectable = false, FontStyle = FontStyle.Italic }); EndUpdate(); _cts = new CancellationTokenSource(); ComboTreeNodeCollection results = new ComboTreeNodeCollection(null); var task = Task.Factory.StartNew(() => OnPerformSearch(new PerformSearchEventArgs(_services.Text, _cts.Token, results)), _cts.Token); task.ContinueWith(t => { if (t.IsFaulted) { results.Clear(); string errorText = t.Exception.InnerExceptions.Select(x => x.Message).FirstOrDefault() ?? "an error occured"; results.Add(new ComboTreeNode(String.Format("({0})", errorText)) { Selectable = false, FontStyle = FontStyle.Italic }); } if (!t.IsCanceled) { ApplySearchResults(results); } }); } else { // wait until the search term is long enough BeginUpdate(); Nodes.Clear(); string msg = String.Format("(type at least {0} characters)", MinSearchTermLength); Nodes.Add(new ComboTreeNode(msg) { Selectable = false, FontStyle = FontStyle.Italic }); EndUpdate(); } } else { if (_inSearchMode) { LeaveSearchMode(false); } } }