首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實現類似百度搜尋框的自動完成下拉提示功能

     編輯:關於C#

需求場景

在 Windows Forms 應用程式中,為 TextBox 控制項提供類似百度搜尋框的自動完成下拉提示功能,支援從資料庫載入歷史輸入記錄,並在使用者離開控制項時自動儲存新輸入。

核心實作類別:AutoComplete

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data.SqlClient;

public class AutoComplete
{
    private readonly List _targetTextBoxes = new List();
    private readonly Dictionary _dataSource = 
        new Dictionary();
    private readonly SqlConnection _connection;

    public AutoComplete(string connectionString)
    {
        _connection = new SqlConnection(connectionString);
        LoadHistoryFromDatabase();
    }

    private void LoadHistoryFromDatabase()
    {
        try
        {
            _connection.Open();
            using (var cmd = new SqlCommand("SELECT name, str FROM AutoComplete", _connection))
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    string key = reader["name"].ToString();
                    string value = reader["str"].ToString();
                    
                    if (!_dataSource.ContainsKey(key))
                        _dataSource[key] = new AutoCompleteStringCollection();
                    
                    _dataSource[key].Add(value);
                }
            }
        }
        finally
        {
            _connection.Close();
        }
    }

    /// 
    /// 為容器內所有 TextBox 啟用自動完成
    /// 
    public void AddAll(Control container)
    {
        foreach (Control ctrl in container.Controls)
        {
            if (ctrl is TextBox textBox)
                Add(textBox);
        }
    }

    /// 
    /// 為單一 TextBox 設定自動完成
    /// 
    public void Add(TextBox textBox)
    {
        if (_targetTextBoxes.Contains(textBox)) return;

        _targetTextBoxes.Add(textBox);
        textBox.Leave += TextBox_Leave;
        
        textBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        textBox.AutoCompleteSource = AutoCompleteSource.CustomSource;

        if (!_dataSource.ContainsKey(textBox.Name))
            _dataSource[textBox.Name] = new AutoCompleteStringCollection();

        textBox.AutoCompleteCustomSource = _dataSource[textBox.Name];
    }

    private void TextBox_Leave(object sender, EventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null || string.IsNullOrWhiteSpace(textBox.Text)) return;

        string key = textBox.Name;
        if (!_dataSource.ContainsKey(key))
            _dataSource[key] = new AutoCompleteStringCollection();

        // 避免重複儲存
        if (!_dataSource[key].Contains(textBox.Text))
        {
            SaveToDatabase(key, textBox.Text);
            _dataSource[key].Add(textBox.Text);
        }
    }

    private void SaveToDatabase(string key, string value)
    {
        try
        {
            _connection.Open();
            // 使用參數化查詢防止 SQL 注入
            using (var cmd = new SqlCommand(
                "INSERT INTO AutoComplete (name, str) VALUES (@name, @str)", _connection))
            {
                cmd.Parameters.AddWithValue("@name", key);
                cmd.Parameters.AddWithValue("@str", value);
                cmd.ExecuteNonQuery();
            }
        }
        finally
        {
            _connection.Close();
        }
    }

    /// 
    /// 清除所有歷史記錄
    /// 
    public void ClearAll()
    {
        foreach (var collection in _dataSource.Values)
            collection.Clear();

        try
        {
            _connection.Open();
            using (var cmd = new SqlCommand("DELETE FROM AutoComplete", _connection))
                cmd.ExecuteNonQuery();
        }
        finally
        {
            _connection.Close();
        }
    }

    // 其他方法:Delete, DeleteAll 等...
}

使用範例

public partial class MainForm : Form
{
    private AutoComplete _autoComplete;

    public MainForm()
    {
        InitializeComponent();
        string connStr = "Data Source=.;Initial Catalog=TestDB;Integrated Security=True";
        _autoComplete = new AutoComplete(connStr);
        _autoComplete.AddAll(this); // 為表單上所有 TextBox 啟用
    }
}

關鍵技術點

  • AutoCompleteMode.SuggestAppend:同時顯示下拉清單並自動補全文字。
  • AutoCompleteSource.CustomSource:使用自訂資料來源 AutoCompleteStringCollection。
  • Leave 事件:使用者離開控制項時觸發,適合儲存最終確認的輸入。
  • 參數化查詢:範例修正原始碼的字串串接風險,採用 SqlParameter 防止 SQL 注入。
  • 資源管理:使用 using 區塊確保 SqlCommand、SqlDataReader 正確釋放。

資料庫結構建議

CREATE TABLE AutoComplete (
    id INT IDENTITY(1,1) PRIMARY KEY,
    name NVARCHAR(100) NOT NULL,  -- 對應 TextBox.Name
    str NVARCHAR(500) NOT NULL,   -- 使用者輸入內容
    created_at DATETIME DEFAULT GETDATE()
);
CREATE INDEX IX_AutoComplete_name ON AutoComplete(name);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved