c#为RichTextBox添加自动补全功能

本文关键字:全功能 添加 RichTextBox | 更新日期: 2023-09-27 18:12:48

我有一个数字列表,我想让一个RichTextBox与自动完成,所以当用户开始输入一个数字,它会给他自动完成选项从列表。

我希望它在RichTextBox中因为我希望用户能够在RichTextBox的新行中书写每个数字,所以每次用户按回车键时,它都会重新完成整个自动补全过程

我真不知道该怎么做这件事。如有任何帮助,我将不胜感激。

谢谢

c#为RichTextBox添加自动补全功能

我将代码粘贴到这里。我从来没有得到过正确的盒子的位置,所以你将不得不使用YOffset和XOffset。

在你的表单OnLoad:
intellisenseRichTextBox.IntellisenseWords = new string[] { "Test", "Foo", "Bar", "Supercalifragilisticexpialidocious" };
intellisenseRichTextBox.YOffset = 132;
intellisenseRichTextBox.XOffset = 70;

和类:

public class NotificationForm : Form
{
    public NotificationForm()
    {
        this.ShowInTaskbar = false;
        //this.Enabled = true;
        this.FormBorderStyle = FormBorderStyle.None;
    }
    protected override bool ShowWithoutActivation
    {
        get
        {
            return true;
        }
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams baseParams = base.CreateParams;
            const int WS_EX_NOACTIVATE = 0x08000000;
            const int WS_EX_TOOLWINDOW = 0x00000080;
            baseParams.ExStyle |= (int)(WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
            return baseParams;
        }
    }
}
public class RichTextBoxIntellisense : RichTextBox
{
    private NotificationForm intelliAutoCompleteForm;
    private ListBox intelliAutoCompleteListBox;
    private bool IsNotificationFormShowing;
    private bool IsFromReplaceTab;
    private bool IsFromMouseClick;
    private int _suggestionCount = 20;
    public string[] IntellisenseWords { get; set; }
    public int YOffset { get; set; }
    public int XOffset { get; set; }
    public int SuggestionCount
    {
        get
        {
            return _suggestionCount;
        }
        set
        {
            _suggestionCount = value;
        }
    }
    public RichTextBoxIntellisense()
    {
        this.AcceptsTab = true;
        this.YOffset = 30;
        intelliAutoCompleteForm = new NotificationForm();
        intelliAutoCompleteForm.Size = new Size(200, 200);
        intelliAutoCompleteForm.TopMost = true;
        intelliAutoCompleteListBox = new ListBox();
        intelliAutoCompleteListBox.Dock = DockStyle.Fill;
        intelliAutoCompleteForm.Controls.Add(intelliAutoCompleteListBox);
        this.TextChanged += RichTextBoxIntellisense_TextChanged;
        this.KeyDown += RichTextBoxIntellisense_KeyDown;
        this.KeyPress += RichTextBoxIntellisense_KeyPress;
        this.SelectionChanged += RichTextBoxIntellisense_SelectionChanged;
        intelliAutoCompleteListBox.Click += IntelliAutoCompleteListBox_Click;
        intelliAutoCompleteListBox.SelectedIndexChanged += IntelliAutoCompleteListBox_SelectedIndexChanged;
        intelliAutoCompleteForm.Show();
        intelliAutoCompleteForm.Hide();
    }
    private void IntelliAutoCompleteListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if(IsFromMouseClick)
        {
            if (intelliAutoCompleteListBox.SelectedIndex >= 0)
            {
                ReplaceCurrentWordWith(intelliAutoCompleteListBox.SelectedItem.ToString());
                IsFromReplaceTab = false;
            }
        }
        IsFromMouseClick = false;
    }
    private void IntelliAutoCompleteListBox_Click(object sender, EventArgs e)
    {
        IsFromMouseClick = true;
    }
    private void RichTextBoxIntellisense_SelectionChanged(object sender, EventArgs e)
    {
        intelliAutoCompleteForm.Hide();
        IsNotificationFormShowing = false;
    }
    private void RichTextBoxIntellisense_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (IsFromReplaceTab)
        {
            e.Handled = true;
            IsFromReplaceTab = false;
        }
        else
        {
            if(e.KeyChar == (char)Keys.Escape)
            {
                intelliAutoCompleteForm.Hide();
                IsNotificationFormShowing = false;
                e.Handled = true;
            }
        }
    }
    private void RichTextBoxIntellisense_KeyDown(object sender, KeyEventArgs e)
    {
        if (IsNotificationFormShowing)
        {
            if (e.KeyCode == Keys.Up)
            {
                if(intelliAutoCompleteListBox.Items.Count > 0)
                {
                    if(intelliAutoCompleteListBox.SelectedIndex < 0)
                    {
                        intelliAutoCompleteListBox.SelectedIndex = 0;
                    }
                    else if(intelliAutoCompleteListBox.SelectedIndex > 0)
                    {
                        intelliAutoCompleteListBox.SelectedIndex = intelliAutoCompleteListBox.SelectedIndex - 1;
                    }
                }
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Down)
            {
                if (intelliAutoCompleteListBox.Items.Count > 0)
                {
                    if (intelliAutoCompleteListBox.SelectedIndex < 0)
                    {
                        intelliAutoCompleteListBox.SelectedIndex = 0;
                    }
                    else if (intelliAutoCompleteListBox.SelectedIndex < intelliAutoCompleteListBox.Items.Count - 1)
                    {
                        intelliAutoCompleteListBox.SelectedIndex = intelliAutoCompleteListBox.SelectedIndex + 1;
                    }
                }
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Enter)
            {
                if(intelliAutoCompleteListBox.SelectedIndex >= 0)
                {
                    ReplaceCurrentWordWith(intelliAutoCompleteListBox.SelectedItem.ToString());
                }
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Tab)
            {
                if (intelliAutoCompleteListBox.SelectedIndex >= 0)
                {
                    ReplaceCurrentWordWith(intelliAutoCompleteListBox.SelectedItem.ToString());
                }
                e.Handled = true;
            }
        }
    }
    private void RichTextBoxIntellisense_TextChanged(object sender, EventArgs e)
    {
        if (IntellisenseWords != null && IntellisenseWords.Length > 0)
        {
            string wordText;
            int lastIndexOfSpace;
            int lastIndexOfNewline;
            int lastIndexOfTab;
            int lastIndexOf;
            if(this.SelectionStart == this.Text.Length)
            {
                if(this.SelectionStart > 0 && this.Text[this.SelectionStart - 1] != ' ' && this.Text[this.SelectionStart - 1] != ''t' && this.Text[this.SelectionStart - 1] != ''n')
                {
                    wordText = this.Text.Substring(0,this.SelectionStart);
                    lastIndexOfSpace = wordText.LastIndexOf(' ');
                    lastIndexOfNewline = wordText.LastIndexOf(''n');
                    lastIndexOfTab = wordText.LastIndexOf(''t');
                    lastIndexOf = Math.Max(Math.Max(lastIndexOfSpace,lastIndexOfNewline),lastIndexOfTab);
                    if (lastIndexOf >= 0)
                    {
                        wordText = wordText.Substring(lastIndexOf + 1);
                    }
                    if (PopulateIntelliListBox(wordText))
                    {
                        ShowAutoCompleteForm();
                    }
                    else
                    {
                        intelliAutoCompleteForm.Hide();
                        IsNotificationFormShowing = false;
                    }
                }
                else
                {
                    intelliAutoCompleteForm.Hide();
                    IsNotificationFormShowing = false;
                }
            }
            else
            {
                char currentChar = this.Text[this.SelectionStart];
                if(this.SelectionStart > 0)
                {
                    if(this.SelectionStart > 0 && this.Text[this.SelectionStart - 1] != ' ' && this.Text[this.SelectionStart - 1] != ''t' && this.Text[this.SelectionStart - 1] != ''n'
                        && (this.Text[this.SelectionStart] == ' ' || this.Text[this.SelectionStart] == ''t' || this.Text[this.SelectionStart] == ''n'))
                    {
                        wordText = this.Text.Substring(0, this.SelectionStart);
                        lastIndexOfSpace = wordText.LastIndexOf(' ');
                        lastIndexOfNewline = wordText.LastIndexOf(''n');
                        lastIndexOfTab = wordText.LastIndexOf(''t');
                        lastIndexOf = Math.Max(Math.Max(lastIndexOfSpace, lastIndexOfNewline), lastIndexOfTab);
                        if (lastIndexOf >= 0)
                        {
                            wordText = wordText.Substring(lastIndexOf + 1);
                        }
                        if(PopulateIntelliListBox(wordText))
                        {
                            ShowAutoCompleteForm();
                        }
                        else
                        {
                            intelliAutoCompleteForm.Hide();
                            IsNotificationFormShowing = false;
                        }
                    }
                    else
                    {
                        intelliAutoCompleteForm.Hide();
                        IsNotificationFormShowing = false;
                    }
                }
                else
                {
                    intelliAutoCompleteForm.Hide();
                    IsNotificationFormShowing = false;
                }
            }
        }
        else
        {
            intelliAutoCompleteForm.Hide();
            IsNotificationFormShowing = false;
        }
    }
    private bool PopulateIntelliListBox(string wordTyping)
    {
        intelliAutoCompleteListBox.Items.Clear();
        List<KeyValuePair<int, string>> tempWords = new List<KeyValuePair<int, string>>();
        string[] outArray;
        for(int i = 0; i < IntellisenseWords.Length; i++)
        {
            if(IntellisenseWords[i].StartsWith(wordTyping, StringComparison.CurrentCultureIgnoreCase))
            {
                tempWords.Add(new KeyValuePair<int, string>(1, IntellisenseWords[i]));
            }
        }
        if(tempWords.Count < _suggestionCount && wordTyping.Length > 1)
        {
            for (int i = 0; i < IntellisenseWords.Length; i++)
            {
                if (IntellisenseWords[i].Contains(wordTyping, StringComparison.CurrentCultureIgnoreCase))
                {
                    if(tempWords.Count(c => c.Value == IntellisenseWords[i]) == 0)
                    {
                        tempWords.Add(new KeyValuePair<int, string>(2, IntellisenseWords[i]));
                    }
                }
            }
        }
        outArray = tempWords.OrderBy(o => o.Key).Take(_suggestionCount).Select(s => s.Value).ToArray();
        intelliAutoCompleteListBox.Items.AddRange(outArray);
        return outArray.Length > 0;
    }
    private void ShowAutoCompleteForm()
    {
        Point tmpPoint = this.PointToClient(this.Location);
        Point tmpSelPoint = this.GetPositionFromCharIndex(this.SelectionStart);
        intelliAutoCompleteForm.Location = new Point((-1 * tmpPoint.X) + tmpSelPoint.X + this.XOffset, (-1 * tmpPoint.Y) + tmpSelPoint.Y + this.Margin.Top + this.YOffset);
        intelliAutoCompleteForm.Show();
        IsNotificationFormShowing = true;
        this.Focus();
    }
    private void ReplaceCurrentWordWith(string Word)
    {
        string startString = "";
        string endString = this.Text.Substring(this.SelectionStart);
        string wordText = this.Text.Substring(0, this.SelectionStart);
        int lastIndexOfSpace = wordText.LastIndexOf(' ');
        int lastIndexOfNewline = wordText.LastIndexOf(''n');
        int lastIndexOfTab = wordText.LastIndexOf(''t');
        int lastIndexOf = Math.Max(Math.Max(lastIndexOfSpace, lastIndexOfNewline), lastIndexOfTab);
        if (lastIndexOf >= 0)
        {
            startString = wordText.Substring(0, lastIndexOf + 1);
            wordText = wordText.Substring(lastIndexOf + 1);
        }
        this.Text = String.Format("{0}{1} {2}", startString, Word, endString);
        if(lastIndexOf >= 0)
        {
            this.SelectionStart = startString.Length + Word.Length + 1;
        }
        else
        {
            this.SelectionStart = Word.Length + 1;
        }
        IsFromReplaceTab = true;
    }
}