Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinForms | C# | AutoComplete in the Middle of a Textbox?

I have a textbox that does autocompletion like so:

txtName.AutoCompleteMode = AutoCompleteMode.Suggest; txtName.AutoCompleteSource = AutoCompleteSource.CustomSource; txtName.AutoCompleteCustomSource = namesCollection; 

It works, but only at the beginning of a textbox. I'd like autocomplete to kick in for any word the user is entering, at any position in the textbox.

like image 809
Chaddeus Avatar asked Sep 17 '09 06:09

Chaddeus


People also ask

Does Microsoft still support WinForms?

"We continue to support and innovate in Windows Forms runtime," said Microsoft's Igor Velikorossov last month in announcing what's new for WinForms in . NET 6. He's a software engineer on the dev team for the 19-year-old product, a free and open-source graphical (GUI) class library included as a part of .

What is difference between WinForms and Windows Forms?

Winforms and Windows Forms are the same thing. Winforms is the shortened name for Windows Forms.

Is WinForms deprecated?

WinForms won't be deprecated until Win32 is ... which could be quite sometime! WPF on the other hand has few direct dependencies on Win32 so could potentially form the basis of a "fresh start" UI layer on a future version of windows.


1 Answers

using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms;  namespace TubeUploader {     public class AutoCompleteTextBox : TextBox     {         private ListBox _listBox;         private bool _isAdded;         private String[] _values;         private String _formerValue = String.Empty;          public AutoCompleteTextBox()         {             InitializeComponent();             ResetListBox();         }          private void InitializeComponent()         {             _listBox = new ListBox();             KeyDown += this_KeyDown;             KeyUp += this_KeyUp;         }          private void ShowListBox()         {             if (!_isAdded)             {                 Parent.Controls.Add(_listBox);                 _listBox.Left = Left;                 _listBox.Top = Top + Height;                 _isAdded = true;             }             _listBox.Visible = true;             _listBox.BringToFront();         }          private void ResetListBox()         {             _listBox.Visible = false;         }          private void this_KeyUp(object sender, KeyEventArgs e)         {             UpdateListBox();         }          private void this_KeyDown(object sender, KeyEventArgs e)         {             switch (e.KeyCode)             {                 case Keys.Tab:                     {                         if (_listBox.Visible)                         {                             InsertWord((String)_listBox.SelectedItem);                             ResetListBox();                             _formerValue = Text;                         }                         break;                     }                 case Keys.Down:                     {                         if ((_listBox.Visible) && (_listBox.SelectedIndex < _listBox.Items.Count - 1))                             _listBox.SelectedIndex++;                          break;                     }                 case Keys.Up:                     {                         if ((_listBox.Visible) && (_listBox.SelectedIndex > 0))                             _listBox.SelectedIndex--;                          break;                     }             }         }          protected override bool IsInputKey(Keys keyData)         {             switch (keyData)             {                 case Keys.Tab:                     return true;                 default:                     return base.IsInputKey(keyData);             }         }          private void UpdateListBox()         {             if (Text == _formerValue) return;             _formerValue = Text;             String word = GetWord();              if (_values != null && word.Length > 0)             {                 String[] matches = Array.FindAll(_values,                                                  x => (x.StartsWith(word, StringComparison.OrdinalIgnoreCase) && !SelectedValues.Contains(x)));                 if (matches.Length > 0)                 {                     ShowListBox();                     _listBox.Items.Clear();                     Array.ForEach(matches, x => _listBox.Items.Add(x));                     _listBox.SelectedIndex = 0;                     _listBox.Height = 0;                     _listBox.Width = 0;                     Focus();                     using (Graphics graphics = _listBox.CreateGraphics())                     {                         for (int i = 0; i < _listBox.Items.Count; i++)                         {                             _listBox.Height += _listBox.GetItemHeight(i);                             // it item width is larger than the current one                             // set it to the new max item width                             // GetItemRectangle does not work for me                             // we add a little extra space by using '_'                             int itemWidth = (int)graphics.MeasureString(((String)_listBox.Items[i]) + "_", _listBox.Font).Width;                             _listBox.Width = (_listBox.Width < itemWidth) ? itemWidth : _listBox.Width;                         }                     }                 }                 else                 {                     ResetListBox();                 }             }             else             {                 ResetListBox();             }         }          private String GetWord()         {             String text = Text;             int pos = SelectionStart;              int posStart = text.LastIndexOf(' ', (pos < 1) ? 0 : pos - 1);             posStart = (posStart == -1) ? 0 : posStart + 1;             int posEnd = text.IndexOf(' ', pos);             posEnd = (posEnd == -1) ? text.Length : posEnd;              int length = ((posEnd - posStart) < 0) ? 0 : posEnd - posStart;              return text.Substring(posStart, length);         }          private void InsertWord(String newTag)         {             String text = Text;             int pos = SelectionStart;              int posStart = text.LastIndexOf(' ', (pos < 1) ? 0 : pos - 1);             posStart = (posStart == -1) ? 0 : posStart + 1;             int posEnd = text.IndexOf(' ', pos);              String firstPart = text.Substring(0, posStart) + newTag;             String updatedText = firstPart + ((posEnd == -1) ? "" : text.Substring(posEnd, text.Length - posEnd));               Text = updatedText;             SelectionStart = firstPart.Length;         }          public String[] Values         {             get             {                 return _values;             }             set             {                 _values = value;             }         }          public List<String> SelectedValues         {             get             {                 String[] result = Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);                 return new List<String>(result);             }         }      }  } 

Sample Usage

using System; using System.Windows.Forms;  namespace AutoComplete {     public partial class TestForm : Form     {         private readonly String[] _values = { "one", "two", "three", "tree", "four", "fivee" };          public TestForm()         {             InitializeComponent();             // AutoComplete is our special textbox control on the form             AutoComplete.Values = _values;         }      } } 
like image 53
Parimal Raj Avatar answered Oct 31 '22 18:10

Parimal Raj