C# 在RichTextBox中键入单词时,将显示隐藏的列表框

C# 在RichTextBox中键入单词时,将显示隐藏的列表框,c#,winforms,autocomplete,C#,Winforms,Autocomplete,我正在研究texteditor,我想知道如何实现自动完成功能 我在单独的类(KeyWord.cs)中有这个字符串集合 我已经在位于主窗体的列表框(lb)中输入了字符串,这些字符串已经排序: lb = new ListBox(); Controls.Add(lb); //lb.Visible = false; KeyWord keywordsL = new KeyWord(); KeyWord eventsL = new KeyWord(); foreach (string str in key

我正在研究texteditor,我想知道如何实现自动完成功能

我在单独的类(KeyWord.cs)中有这个字符串集合

我已经在位于主窗体的列表框(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(还带有highlights选项)声明为rtb


现在我关心的是,如何使它像“contexthint”一样,当我在RichTextBox(rtb)中键入字母“A”时,一个隐藏的列表框将出现在鼠标指针所在的位置,然后列表框中列出的字符串中的所有“A”都将出现。最后,当我从列表框中选择显示的字符串时,该字符串将添加到RichTextBox中的

实现这一点的简单方法是这样做:

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();
}
private List autoCompleteList=new List();
公共表格1()
{
添加(“自动完成的项目”);
}
...
私有void textBox1\u TextChanged(对象发送者,System.EventArgs e)
{
listBox1.Items.Clear();
如果(textBox1.Text.Length==0)
{
hideAutoCompleteMenu();
返回;
}
点游标PT=游标位置;
listBox1.Location=PointToClient(cursorPt);
foreach(自动完成列表中的字符串s)
{
如果(s.StartsWith(textBox1.Text))
{
列表框1.项目。添加;
listBox1.Visible=true;
}
}
}
私有无效hideAutoCompleteMenu()
{
listBox1.Visible=false;
}
私有无效列表框1\u SelectedIndexChanged(对象发送方,System.EventArgs e)
{
textBox1.Text=listBox1.Items[listBox1.SelectedIndex].ToString();
hideAutoCompleteMenu();
}

但是,在实现这个特性时,您必须考虑所有可能的拐角情况,例如

  • 如果用户在键入内容时按ESC/Enter,会发生什么情况
  • 如果用户失去对richtextbox的关注,会发生什么情况
  • 当列表框打开时,如何处理向上和向下箭头键
  • 当列表框中有大量项目需要搜索时,会出现性能问题吗

虽然上面的一些问题只是处理其他事件的问题,但上面显示的代码是实现您想要的东西的一种非常快速和肮脏的方式,但实际上,您正在做的似乎是为已经可用的东西重新发明轮子。我建议您查看AvaloneEdit和FastColoredTextBox中的源代码,看看这是如何实现的。

与键入“A”然后键入“s”时一样,所有第一个字母“as”都将排序并保留在列表框中?您是指类似intellisense中的自动完成菜单吗。。?请仔细查看“是”或“是”。@关于链接,我无法在此项目中使用任何参考资料。因此我需要代码。@Elegaic从头开始实现自动完成绝非易事,这是一个需要详细讨论的庞大材料。看看这些项目的源代码,看看这些项目是如何实现自动完成的,这应该会让你知道如何去做。我认为这只是一个条件代码的问题?因为我已经有了与标签和字符串相同的高光代码…我只是遇到了一些问题。avalon和fastcoloredtextbox都有一个自定义工具和参考w/c,我找不到代码是如何工作的…:(
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();
}