Is there any way to use autocomplete with multiple words inside the textbox in a winform?

后端 未结 1 1284
青春惊慌失措
青春惊慌失措 2021-01-27 17:53

I want to show the suggested words using autocomplete for the textbox. For instance, i type Tod... all words from my database that starts with \"tod\" will show but after I chos

1条回答
  •  借酒劲吻你
    2021-01-27 18:03

    So a basic "Roll Your Own" solution will work like so:

    string[] arr = new string[] { "sn k", "sn k", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" };
    
    private ListBox autoListBox;
    
    private void Form1_Load(object sender, EventArgs e)
    {
        this.txtInput.TextChanged += txtInput_TextChanged;
        CreateAutocompleteListBox();
    }
    
    private void txtInput_TextChanged(object sender, EventArgs e)
    {
        showAutoCompleteList();
    }
    
    private void CreateAutocompleteListBox()
    {
        this.autoListBox = new ListBox()
        {
            Left = this.txtInput.Left,
            Top = this.txtInput.Top + this.txtInput.Height,
            Width = 100,
            Height = 75
        };
    
        this.autoListBox.Click += autoListBox_Click;
        this.autoListBox.KeyDown += autoListBox_KeyDown;
        this.autoListBox.Visible = false;
        this.Controls.Add(this.autoListBox);
    }
    
    private void autoListBox_Click(object sender, EventArgs e)
    {
        AutocompleteFinished();
    }
    
    private void autoListBox_KeyDown(object sender, KeyEventArgs e)
    {
        var finishCodes = new List { Keys.Return, Keys.Space };
        if (finishCodes.Contains(e.KeyCode))
        {
            AutocompleteFinished();
        }
    }
    
    private string GetLastWord(TextBox txt)
    {
        return (" " + txt.Text).Split(' ').LastOrDefault() ?? "";
    }
    
    private void showAutoCompleteList()
    {
        this.autoListBox.Left = this.txtInput.Left;
        this.autoListBox.Top = this.txtInput.Top + this.txtInput.Height + 2;
        var lastWord = GetLastWord(this.txtInput);
    
        this.autoListBox.Items.Clear();
        this.autoListBox.Items.AddRange(this.arr.Where(aw => aw.ToLower().StartsWith(lastWord.ToLower())).ToArray());
        this.autoListBox.Visible = true;
    }
    
    private void txtInput_KeyDown(object sender, KeyEventArgs e)
    {
        // These keys show auto-complete selector
        var activatorCodes = new List { Keys.Up, Keys.Down };
        if (activatorCodes.Contains(e.KeyCode))
        {
            SwitchToAutoCompleteList();
        }
    }
    
    private void SwitchToAutoCompleteList()
    {
        this.autoListBox.Focus();
        this.autoListBox.SelectedIndex = 0;
    }
    
    private void AutocompleteFinished()
    {
        var lastWord = GetLastWord(this.txtInput);
        var nextWord = this.autoListBox.Text;
        this.txtInput.Text = this.txtInput.Text.Substring(0, this.txtInput.Text.Length - lastWord.Length);
        this.txtInput.AppendText(nextWord);
        this.autoListBox.Visible = false;
    }
    

    This ought to do what you want, it will show autocomplete for each word! One could add a little finesse, such as moving the autocomplete box around as the text moves on.

    0 讨论(0)
提交回复
热议问题