简体   繁体   中英

How to make winforms textbox autocomplete correct capitalisation?

Using a winforms textbox with autocomplete set to SuggestAppend I can type out part of a string and the rest will be suggested to me fine.

If a user types "smi" looking for "Smith, John" and then autocompletes the rest of the string by tabbing then the textbox contains "smith, John". But, if the user clicks on the name then the capitalisation is correct.

Is there a way I can get the autocomplete to re-capitalise the user inputted part of the string when the suggestion is accepted by tabbing?

在此处输入图像描述

Pressing tab leads to:

在此处输入图像描述

Clicking name leads to (this is what I want):

在此处输入图像描述

To handle this situation I handled the textbox Leave event. The idea is to split the text by comma, uppercase the first letter of the resulting strings, then join the strings back together.

private void textBox1_Leave(object sender, EventArgs e)
{
  string[] strings = this.textBox1.Text.Split(new char[] { ',' });

  for (int i = 0; i < strings.Length; i++)
  {
    strings[i] = string.Format("{0}{1}", char.ToUpper(strings[i][0]), strings[i].Substring(1));
  }

  this.textBox1.Text = string.Join(",", strings);
}

Here's the function I came up with the end, it replaces the textbox's content with a line from the AutoCompleteCustomSource of the textbox (sorted alphabetically).

So, this will still work for any case (eg if user entered "aLLeN" it would still correct to "Allen,Charlie (ID:104)"

private void fixContent()
{
    String text = txtAutoComplete.Text;
    List<String> matchedResults = new List<String>();

    //Iterate through textbox autocompletecustomsource
    foreach (String ACLine in txtAutoComplete.AutoCompleteCustomSource)
    {
        //Check ACLine length is longer than text length or substring will raise exception
        if (ACLine.Length >= text.Length)
        {
            //If the part of the ACLine with the same length as text is the same as text, it's a possible match
            if (ACLine.Substring(0, text.Length).ToLower() == text.ToLower())
                matchedResults.Add(ACLine);
        }
    }

    //Sort results and set text to first result
    matchedResults.Sort();
    txtAutoComplete.Text = matchedResults[0] 
}

Thanks to OhBeWise I attached this to the textbox leave event:

private void txtAutoComplete_Leave(object sender, EventArgs e)
{
    fixContent();
}

But also I needed to cover situations when the autocomplete has been accepted which occur when enter, tab, left and right are pressed. Attaching this to the keydown event doesn't work because I think the autocomplete captures the event beforehand, so I attached to the previewkeydown event:

private void txtAutoComplete_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    Keys key = (Keys)e.KeyCode;

    if (key == Keys.Enter || key == Keys.Tab || key == Keys.Left || key == Keys.Right)
    {
        fixContent();
    }
}
simple ;
 private void textbox_TextChanged(object sender, EventArgs e)
    {
        AutoCompleteStringCollection a = new AutoCompleteStringCollection();
        a = textbox.AutoCompleteCustomSource;

        for (int i = 0; i < a.Count; i++)
        {
            if (a[i].ToLower() == textbox.Text.ToLower())
            {
                textbox.Text= a[i].ToString();
                break;
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM