2011-01-07 8 views
11

Tengo una lista de palabras. La lista contiene alrededor de 100-200 cadenas de texto (en realidad son los nombres de las estaciones de metro).Cómo hacer un cuadro de texto de autocompletar en una aplicación de escritorio de winforms

Quiero hacer un cuadro de texto de autocompletar. Para un ejemplo, el usuario presiona la letra 'N', luego aparece una (adecuada) opción (solo una opción). El final debe ser seleccionado.

¿Cómo hacer eso?

PS1: supongo, hay un control de cuadro de texto con una propiedad algo como esto:

List<string> AppropriateOptions{/* ... */} 

PS2: lo siento por mi Inglés. Si no entendiste -> pregúntame y trataré de explicarlo!

Respuesta

0

que desea establecer el TextBox.AutoCompleteSource a CustomSource y luego añadir todas sus cadenas a su AutoCompleteCustomSource propiedad, que es un StringCollection. Entonces deberías ser bueno para ir.

15

Sólo en caso de leniel @ enlace deja de funcionar, aquí hay un código que hace el truco:

AutoCompleteStringCollection allowedTypes = new AutoCompleteStringCollection(); 
allowedTypes.AddRange(yourArrayOfSuggestions); 
txtType.AutoCompleteCustomSource = allowedTypes; 
txtType.AutoCompleteMode = AutoCompleteMode.Suggest; 
txtType.AutoCompleteSource = AutoCompleteSource.CustomSource; 
+0

Gracias Joel, funcionó para mí. Podemos seleccionar el texto de sugerencia con las teclas de flecha arriba y abajo. Lo intenté pero no me lo permitió. – rakesh

+0

@rakesh No he trabajado en winforms desde hace un tiempo, y no recuerdo si es una característica "estándar" o implica un esfuerzo extra. Lo siento – Joel

+1

Gracias por proporcionar la esencia en lugar de una respuesta de solo enlace. – Jess

0

El enlace de respuesta por Leniel fue en vb.net, gracias a Joel por su entrada. El suministro de mi código para que sea más explícito:

private void InitializeTextBox() 
{ 

    AutoCompleteStringCollection allowedStatorTypes = new AutoCompleteStringCollection(); 
    var allstatortypes = StatorTypeDAL.LoadList<List<StatorType>>().OrderBy(x => x.Name).Select(x => x.Name).Distinct().ToList(); 

    if (allstatortypes != null && allstatortypes.Count > 0) 
    { 
     foreach (string item in allstatortypes) 
     { 
      allowedStatorTypes.Add(item); 
     } 
    } 

    txtStatorTypes.AutoCompleteMode = AutoCompleteMode.Suggest; 
    txtStatorTypes.AutoCompleteSource = AutoCompleteSource.CustomSource; 
    txtStatorTypes.AutoCompleteCustomSource = allowedStatorTypes; 
} 
0

Quiero añadir que el autocompletar estándar de cuadro de texto sólo funciona desde el comienzo de sus cadenas, por lo que si se golpea N se encontró sólo cadenas que comienzan con N. Si quieres tener algo mejor, tienes que usar un control diferente o implementar el comportamiento por ti mismo (es decir, reaccionar en el evento TextChanged con un temporizador para retrasar la ejecución, luego filtrar la búsqueda de listas de tokens con IndexOf (inputString) y luego configurar tu AutoCompleteSource en la lista filtrada.

0

Utilizar un cuadro combinado en lugar de un cuadro de texto. el siguiente ejemplo autocompletará, igualando cualquier pieza del texto, no sólo por las iniciales.

Esto debería ser una forma completa, sólo tiene que añadir su propio origen de datos y nombres de columna de origen de datos. :-)

using System; 
using System.Data; 
using System.Windows.Forms; 

public partial class frmTestAutocomplete : Form 
{ 

private DataTable maoCompleteList; 
private const string MC_DISPLAY_COL = "name"; 
private const string MC_ID_COL = "id"; 

public frmTestAutocomplete() 
{ 
    InitializeComponent(); 
} 

private void frmTestAutocomplete_Load(object sender, EventArgs e) 
{ 

     maoCompleteList = oData.PurificationRuns; 
     maoCompleteList.CaseSensitive = false; //turn off case sensitivity for searching 

     testCombo.DisplayMember = MC_DISPLAY_COL; 
     testCombo.ValueMember = MC_ID_COL; 
     testCombo.DataSource = GetDataTableFromDatabase(); 
     testCombo.SelectedIndexChanged += testCombo_SelectedIndexChanged; 
     testCombo.KeyUp += testCombo_KeyUp; 
} 


private void testCombo_KeyUp(object sender, KeyEventArgs e) 
{ 
    //use keyUp event, as text changed traps too many other evengts. 

    ComboBox oBox = (ComboBox)sender; 
    string sBoxText = oBox.Text; 

    DataRow[] oFilteredRows = maoCompleteList.Select(MC_DISPLAY_COL + " Like '%" + sBoxText + "%'"); 

    DataTable oFilteredDT = oFilteredRows.Length > 0 
          ? oFilteredRows.CopyToDataTable() 
          : maoCompleteList; 

    //NOW THAT WE HAVE OUR FILTERED LIST, WE NEED TO RE-BIND IT WIHOUT CHANGING THE TEXT IN THE ComboBox. 

    //1).UNREGISTER THE SELECTED EVENT BEFORE RE-BINDING, b/c IT TRIGGERS ON BIND. 
    testCombo.SelectedIndexChanged -= testCombo_SelectedIndexChanged; //don't select on typing. 
    oBox.DataSource = oFilteredDT; //2).rebind to filtered list. 
    testCombo.SelectedIndexChanged += testCombo_SelectedIndexChanged; 


    //3).show the user the new filtered list. 
    oBox.DroppedDown = true; //this will overwrite the text in the ComboBox, so 4&5 put it back. 

    //4).binding data source erases text, so now we need to put the user's text back, 
    oBox.Text = sBoxText; 
    oBox.SelectionStart = sBoxText.Length; //5). need to put the user's cursor back where it was. 


} 

private void testCombo_SelectedIndexChanged(object sender, EventArgs e) 
{ 

    ComboBox oBox = (ComboBox)sender; 

    if (oBox.SelectedValue != null) 
    { 
     MessageBox.Show(string.Format(@"Item #{0} was selected.", oBox.SelectedValue)); 
    } 
} 

} 

//===================================================================================================== 
//  code from frmTestAutocomplete.Designer.cs 
    //===================================================================================================== 
    partial class frmTestAutocomplete 

{ 
    /// <summary> 
    /// Required designer variable. 
    /// </summary> 
    private System.ComponentModel.IContainer components = null; 

    /// <summary> 
    /// Clean up any resources being used. 
    /// </summary> 
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
protected override void Dispose(bool disposing) 
{ 
    if (disposing && (components != null)) 
    { 
     components.Dispose(); 
    } 
    base.Dispose(disposing); 
} 

#region Windows Form Designer generated code 

/// <summary> 
/// Required method for Designer support - do not modify 
/// the contents of this method with the code editor. 
/// </summary> 
private void InitializeComponent() 
{ 
    this.testCombo = new System.Windows.Forms.ComboBox(); 
    this.SuspendLayout(); 
    // 
    // testCombo 
    // 
    this.testCombo.FormattingEnabled = true; 
    this.testCombo.Location = new System.Drawing.Point(27, 51); 
    this.testCombo.Name = "testCombo"; 
    this.testCombo.Size = new System.Drawing.Size(224, 21); 
    this.testCombo.TabIndex = 0; 
    // 
    // frmTestAutocomplete 
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
    this.ClientSize = new System.Drawing.Size(292, 273); 
    this.Controls.Add(this.testCombo); 
    this.Name = "frmTestAutocomplete"; 
    this.Text = "frmTestAutocomplete"; 
    this.Load += new System.EventHandler(this.frmTestAutocomplete_Load); 
    this.ResumeLayout(false); 

} 

#endregion 

private System.Windows.Forms.ComboBox testCombo; 

}

Cuestiones relacionadas