Скрытый ListBox появится при наборе слов в RichTextBox

Я работаю над texteditor, и я хотел бы знать, как реализовать функцию автозаполнения.

У меня есть эта коллекция строк в моем отдельном классе (KeyWord.cs)

public String[] keywords = { "abstract", "as", "etc." };
public String[] events = { "AcceptRejectRule", "AccessibleEvents", "etc.2" };

что я уже ввел строки в ListBox (lb), расположенные в моей главной форме, которые уже отсортированы:

lb = new ListBox();
Controls.Add(lb);
//lb.Visible = false;

KeyWord keywordsL = new KeyWord();
KeyWord eventsL = new KeyWord();
foreach (string str in keywordsL.keywords)
{
    lb.Items.Add(str);
}
foreach (string str in eventsL.events)
{
    lb.Items.Add(str);
}

и RichTextBox, который служил редактором (с опцией подсветки), объявленным как rtb.

Теперь меня беспокоило то, как я могу сделать его похожим на его "contextxint", например, когда я набираю букву "A" в RichTextBox(rtb), появится скрытый список в том месте, где был указатель мыши, а затем все "A" в начале строки, перечисленные в списке появится. Наконец, когда я выбираю показанную строку из списка, строка будет добавлена ​​в RichTextBox?

1 ответ

Решение

Простой способ реализовать это - сделать что-то вроде этого:

private List<string> autoCompleteList = new List<string>();

public Form1()
{
    autoCompleteList.Add("Items for the autocomplete");
}
...

private void textBox1_TextChanged(object sender, System.EventArgs e)
{
    listBox1.Items.Clear();
    if (textBox1.Text.Length == 0)
    {
        hideAutoCompleteMenu();
        return;
    }

    Point cursorPt = Cursor.Position;
    listBox1.Location = PointToClient(cursorPt);

    foreach (String s in autoCompleteList)
    {
        if (s.StartsWith(textBox1.Text))
        {
            listBox1.Items.Add(s);
            listBox1.Visible = true;
        }

    }
 }

private void hideAutoCompleteMenu()
{
    listBox1.Visible = false;
}

private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
    textBox1.Text = listBox1.Items[listBox1.SelectedIndex].ToString();
    hideAutoCompleteMenu();
}

Однако при реализации этой функции вы должны учитывать все возможные варианты, например:

  • Что произойдет, если пользователь нажмет ESC/Enter во время ввода чего-либо?
  • Что произойдет, если пользователь потеряет фокус на richtextbox?
  • Как насчет обработки клавиш со стрелками вверх и вниз, когда список открыт?
  • Проблема с производительностью, когда в списке есть тонны элементов для поиска?

Хотя некоторые из вышеперечисленных проблем связаны только с обработкой дополнительных событий, приведенный выше код является очень быстрым и грязным способом реализации того, что вы хотите, но на самом деле кажется, что вы делаете - заново изобретаете колесо для того, что уже доступно. Я предлагаю вам взглянуть на исходный код в AvalonEdit и FastColoredTextBox, чтобы увидеть, как это действительно сделано.

Другие вопросы по тегам