Как сделать автозаполнение текстового поля в настольном приложении winforms - PullRequest
12 голосов
/ 07 января 2011

У меня есть список слов. Список содержит около 100-200 текстовых строк (собственно, это названия станций метро).

Я хочу сделать автозаполнение текстового поля. Например, пользователь нажимает букву «N», затем появляется соответствующая опция (окончание) (только одна опция). Конец должен быть выбран.

Как это сделать?

PS1: Полагаю, есть элемент управления для текстового поля со свойством примерно так:

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

PS2: простите за мой английский. Если вы не поняли -> спросите меня, и я постараюсь объяснить!

Ответы [ 6 ]

17 голосов
/ 13 августа 2013

На случай, если ссылка @ leniel выйдет из строя, вот код, который решает проблему:

AutoCompleteStringCollection allowedTypes = new AutoCompleteStringCollection();
allowedTypes.AddRange(yourArrayOfSuggestions);
txtType.AutoCompleteCustomSource = allowedTypes;
txtType.AutoCompleteMode = AutoCompleteMode.Suggest;
txtType.AutoCompleteSource = AutoCompleteSource.CustomSource;
2 голосов
/ 11 февраля 2017

Используйте ComboBox вместо TextBox.В следующем примере будет выполнено автозаполнение, соответствующее любому фрагменту текста, а не только начальным буквам.

Это должна быть полная форма, просто добавьте свой собственный источник данных и имена столбцов источника данных.: -)

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;

}

0 голосов
/ 10 августа 2018

Используйте поле со списком, задайте его источник данных или задайте жестко запрограммированные записи, но задайте следующие свойства:

    AutoCompleteMode = Suggest;
    AutoCompleteSource = ListItems;
0 голосов
/ 27 июля 2016

Я хочу добавить, что стандартное автозаполнение для TextBox работает только с начала ваших строк, поэтому, если вы нажмете N, будут найдены только строки, начинающиеся с N. Если вы хотите получить что-то лучше, вы должны использовать какой-то другой элемент управления или реализовать поведение для себя (то есть реагировать на событие TextChanged с некоторым таймером, чтобы задержать выполнение, чем фильтровать поиск по списку токенов с помощью IndexOf (inputString), а затем установить AutoCompleteSource на отфильтрованный список.

0 голосов
/ 11 марта 2014

Ссылка на ответ от Leniel была на vb.net, спасибо Джоэл за вашу запись.Предоставление моего кода, чтобы сделать его более явным:

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 голосов
/ 07 января 2011

Вы хотите установить TextBox.AutoCompleteSource в CustomSource, а затем добавить все свои строки в его свойство AutoCompleteCustomSource, которое является StringCollection.Тогда тебе надо идти.

...