Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Show AutoComplete Programmatically without entering a text

C# TextBox AutoCompleteCustomSource has a List<string>, AutoCompleteMode = Suggest.

I can see the List when I type a Letter.

How to show entire list without Typing a Letter Programmatically? This must be done while the User presses the Down Arrow Key in the TextBox.

Is there any Win32 API Available?

My Solution

I refined a Better Solution.

Add a ListBox Control to the form and make it as Visible = false

int curSelIndex = -1;

The below given Code will be executed Form_Load Event.

txtEmpId.AutoCompleteCustomSource.AddRange(EmpIds.ToArray());
lstAutoComplete.Items.Clear();
lstAutoComplete.Items.AddRange(EmpIds.ToArray());
txtEmpId.KeyDown += (ks, ke) =>
{
    if (!(ke.KeyCode == Keys.Down || 
          ke.KeyCode == Keys.Up || 
          ke.KeyCode == Keys.Enter)) 
    { 
        lstAutoComplete.Visible = false; 
        return; 
    }
    ke.Handled = true;
    if (ke.KeyCode == Keys.Enter)
    {
        if (lstAutoComplete.Visible)
        {
            var str = lstAutoComplete.SelectedItem + "";
            // Process the Selected Item and set to TextBox.
        }
    }
    if (!lstAutoComplete.Visible && txtEmpId.Focused)
    {
        var loc = txtEmpId.Location;
        loc.Y += txtEmpId.Height;
        lstAutoComplete.Location = loc;
        lstAutoComplete.Size = txtEmpId.Size;
        lstAutoComplete.Height = 100;
        lstAutoComplete.SelectedIndex = 0;
        curSelIndex = 0;
        lstAutoComplete.Visible = true;
    }
    else if(lstAutoComplete.Visible && txtEmpId.Focused)
    {
        if (ke.KeyCode == Keys.Down)
        {
            curSelIndex++;
            if (curSelIndex >= lstAutoComplete.Items.Count)
                curSelIndex = lstAutoComplete.Items.Count - 1;
            if (lstAutoComplete.Items.Count > 0)
                lstAutoComplete.SelectedIndex = curSelIndex;
        }
        else if (ke.KeyCode == Keys.Up)
        {
            curSelIndex--;
            if (curSelIndex < 0)
                curSelIndex = 0;
            if (lstAutoComplete.Items.Count > 0)
                lstAutoComplete.SelectedIndex = curSelIndex;
        }
    }
};
txtEmpId.Leave += (ls, le) => lstAutoComplete.Visible = false;
like image 905
Gokul E Avatar asked Mar 21 '23 03:03

Gokul E


1 Answers

I didn't find any API for your problem, so I just make a my own suggestion box by using ListBox to show when the Down Arrow Key is pressed, when you do other operation, it disappeares. I hope it is useful to you. code sample is bellow:

//string datasource
List<string> strList = null;
//suggestion listbox
ListBox sugBox = null;

public FrmTextSuggest()
{
    InitializeComponent();
    //setting the textbox control
    strList = new List<string>()
    {
        "USA",
        "England",
        "China",
        "Japan",
        "Korea",
        "India",
        "France",
        "Canada"
    };
    var autoCollection = new AutoCompleteStringCollection();
    autoCollection.AddRange(strList.ToArray());
    this.txtCountry.AutoCompleteCustomSource = autoCollection;
    this.txtCountry.AutoCompleteMode = AutoCompleteMode.Suggest;
    this.txtCountry.AutoCompleteSource = AutoCompleteSource.CustomSource;

    //register the Down Arrow Key event
    this.txtCountry.KeyDown += new KeyEventHandler(txtCountry_KeyDown);
}

void txtCountry_KeyDown(object sender, KeyEventArgs e)
{
    //show the your own suggestion box when pressing down arrow and the text box is empty
    if (e.KeyCode == Keys.Down && txtCountry.Text.Trim().Equals(""))
    {
        sugBox = new ListBox();
        //define the box
        sugBox.Width = txtCountry.Width;
        Point p = txtCountry.Location;
        p.Y += txtCountry.Height;
        sugBox.Location = p;
        sugBox.Items.AddRange(strList.ToArray());
        //copy the value to the textbox when selected index changed.
        sugBox.SelectedIndexChanged += new EventHandler(sugBox_SelectedIndexChanged);
        //show box
        if (sugBox.Items.Count > 0)
        {
            sugBox.SelectedIndex = 0;
            this.Controls.Add(sugBox);
            sugBox.Focus();
        }
    }
    //remove and hide your own suggestion box when other operation
    else
    {
        if (sugBox != null && this.Controls.Contains(sugBox))
        {
            this.Controls.Remove(sugBox);
            sugBox.Dispose();
            sugBox = null;
        }
    }
}

void sugBox_SelectedIndexChanged(object sender, EventArgs e)
{
    string selText = this.sugBox.SelectedItem.ToString();
    if (!string.IsNullOrEmpty(selText))
    {
        this.txtCountry.Text = selText;
    }
}

here is my result of test: result picture1

result picture2

like image 89
Scott Yang Avatar answered Apr 06 '23 15:04

Scott Yang