2011-01-07 7 views
11

Ho un elenco di parole. L'elenco contiene circa 100-200 stringhe di testo (i nomi delle stazioni della metropolitana in realtà).Come creare una casella di testo di completamento automatico in un'applicazione desktop Winforms

Desidero creare una casella di testo con completamento automatico. Per un esempio, l'utente preme la lettera 'N', quindi compare un'opzione appropriata (di fine) (solo un'opzione). Il finale deve essere selezionato.

Come fare?

PS1: Credo che, non v'è un controllo TextBox con un qualcosa di proprietà come questa:

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

PS2: mi dispiace per il mio inglese. Se non hai capito -> chiedimi e proverò a spiegare!

risposta

0

si desidera impostare il TextBox.AutoCompleteSource-CustomSource e quindi aggiungere tutte le corde per la sua proprietà AutoCompleteCustomSource, che è un StringCollection. Allora dovresti essere bravo ad andare.

15

Solo nel caso @ collegamento del leniel va giù, ecco qualche codice che fa il trucco:

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

Grazie Joel, ha funzionato per me. Possiamo selezionare il testo del suggerimento con i tasti freccia su e giù. Ho provato ma non mi ha permesso. – rakesh

+0

@rakesh Non ho ancora lavorato su winforms per un po 'di tempo, e non ricordo se sia una funzionalità "standard" o che implichi uno sforzo extra. Scusa – Joel

+1

Grazie per aver fornito l'elenco anziché una risposta di solo collegamento. – Jess

0

Il legame risposta da Leniel era in vb.net, grazie Joel per la voce. Fornire il mio codice per renderlo più esplicito:

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

voglio aggiungere che il completamento automatico standard per TextBox funziona solo dall'inizio delle corde, quindi se si colpisce N sarà trovato solo le stringhe che iniziano con N. Se vuoi avere qualcosa di meglio, devi usare qualche controllo diverso o implementare il comportamento per te stesso (cioè reagire su Event TextChanged con qualche timer per ritardarne l'esecuzione, piuttosto che filtrare la tua tokenlist cercando con IndexOf (inputString) e quindi impostare AutoCompleteSource su l'elenco filtrato.

0

Utilizzare un ComboBox invece di una TextBox. l'esempio che segue completamento automatico, abbinando qualsiasi pezzo di testo, non solo le lettere iniziali.

Questa dovrebbe essere una forma completa, basta aggiungere la tua fonte dati e nomi delle colonne dell'origine dati :-)

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; 

}