internal void DoAutocomplete(bool forced) { if (!Menu.Enabled) { Menu.Close(); return; } visibleItems.Clear(); selectedItemIndex = 0; VerticalScroll.Value = 0; //get fragment around caret Range fragment = tb.Selection.GetFragment(Menu.SearchPattern); string text = fragment.Text; //calc screen point for popup menu Point point = tb.PlaceToPoint(fragment.End); point.Offset(2, tb.CharHeight); if (forced || (text.Length >= Menu.MinFragmentLength && tb.Selection.IsEmpty)) { Menu.Fragment = fragment; bool foundSelected = false; //build popup menu foreach (var item in sourceItems) { item.Parent = Menu; CompareResult res = item.Compare(text); if (res == CompareResult.ExactAndReplace) { tb.TextSource.Manager.BeginAutoUndoCommands(); try { DoAutocomplete(item, fragment); return; } finally { tb.TextSource.Manager.EndAutoUndoCommands(); } } else if (res != CompareResult.Hidden) { visibleItems.Add(item); } if (res == CompareResult.VisibleAndSelected && !foundSelected) { foundSelected = true; selectedItemIndex = visibleItems.Count - 1; } } if (foundSelected) { AdjustScroll(); DoSelectedVisible(); } } //show popup menu if (Count > 0) { if (!Menu.Visible) { CancelEventArgs args = new CancelEventArgs(); Menu.OnOpening(args); if (!args.Cancel) { Menu.Show(tb, point); } } else { Invalidate(); } } else { Menu.Close(); } }